Toggling Item State
We have the ability to add items, but now we need to extend their functionality to allow for indicating that a particular item has been completed. We also want the ability to “reset” the completion state of a particular checklist.
Add the ability to toggle to the service
We will start with allowing a particular item in a checklist to be toggled between checked/unchecked.
The approach here will be the same as any other state change we would approach. Generally, we want to:
- Add a source for the action that will be nexted
- Subscribe to that source
- Have the reducer update the state signal
The reducer for this one is actually a bit tricky, but go ahead and see how much
of this you can implement on your own in the ChecklistItemService
.
Click here to reveal solution
Solution
Add the following source to
ChecklistItemService
:
toggle$ = new Subject<RemoveChecklistItem>();
It might strike you as a bit odd that the type is RemoveChecklistItem
that it
just because the toggle needs the same information — just the id
of the item
being toggled.
Add the following reducer:
this.toggle$.pipe(takeUntilDestroyed()).subscribe((checklistItemId) =>
this.state.update((state) => ({
...state,
checklistItems: state.checklistItems.map((item) =>
item.id === checklistItemId
? { ...item, checked: !item.checked }
: item
),
}))
);
There is nothing new going on here — although the reducer step looks a little
complex, the basic idea is that to overwrite the old checklistItems
it maps
through all of them and if it finds one matching the given checklistItemId
it
will toggle its checked
value.
NOTE: Technically right now we do not need to spread the existing ...state
as checklistItems
is the only property on the state. However, I will always
spread the previous state by default as it is likely at some point that more
properties will be added to the state (and, in fact, we will be doing that later
for this particular service).
Add a checkbox to the checklist item
Now that we have support for toggling an item in the service, we just need to interact with it.
Add the following output to
ChecklistItemListComponent
:
toggle = output<RemoveChecklistItem>();
Add a toggle button to the template of the
ChecklistItemListComponent
: