
Existing member? Log in and continue learning

See if you like it, start the course for free!

Unlock full course by purchasing a membership
Creating Checklist Items
Creating Checklist Items
The path we take to implement this feature is going to look pretty similar to creating the checklists, and it will be the same with just about any feature we would implement.
Create the ChecklistItem Interface
We are creating a new entity in our application now — items that belong to a specific checklist. We are first going to define a new type that represents this entity in the application.
import { RemoveChecklist } from './checklist';
export interface ChecklistItem { id: string; checklistId: string; title: string; checked: boolean;}
export type AddChecklistItem = { item: Omit<ChecklistItem, 'id' | 'checklistId' | 'checked'>; checklistId: RemoveChecklist;};export type EditChecklistItem = { id: ChecklistItem['id']; data: AddChecklistItem['item'];};export type RemoveChecklistItem = ChecklistItem['id'];
In general, this is the same idea as our Checklist
type but there is some
extra weirdness happening here. First of all, our ChecklistItem
type is just
different — as well as the title
we also have a checklistId
to indicate what
Checklist
it belongs to, and a checked
to indicated whether it is currently
in the completed state or not.
We have the same style of types for adding and editing as we did with the
Checklist
but for this one we also have our checklistId
property based on
whatever the RemoveChecklist
type is from our Checklist
interfaces.
We could just give checklistId
a type of string
which would match the id
from our Checklist
interface. This is just a bit safer because if we ever
update the type of the id
in Checklist
we won’t need to remember to change
this too.
Creating the Checklist Item service
Our checklist service was created in the shared/data-access
folder because it
is used by multiple features in the application. However, our
ChecklistItemService
will only be used by the checklist item feature — so, we
will store it inside of the checklist/data-access
folder.
import { Injectable, computed, signal } from '@angular/core';import { takeUntilDestroyed } from '@angular/core/rxjs-interop';import { Subject } from 'rxjs';import { AddChecklistItem, ChecklistItem,} from '../../shared/interfaces/checklist-item';
export interface ChecklistItemsState { checklistItems: ChecklistItem[];}
@Injectable({ providedIn: 'root',})export class ChecklistItemService { // state private state = signal<ChecklistItemsState>({ checklistItems: [], });
// selectors checklistItems = computed(() => this.state().checklistItems);
// sources add$ = new Subject<AddChecklistItem>();
constructor() { this.add$.pipe(takeUntilDestroyed()).subscribe((checklistItem) => this.state.update((state) => ({ ...state, checklistItems: [ ...state.checklistItems, { ...checklistItem.item, id: Date.now().toString(), checklistId: checklistItem.checklistId, checked: false, }, ], })) ); }}
Again, nothing really new here — this is almost identical to what we did with
the ChecklistService
. Our reducer is a bit more complicated so let’s talk
through what is happening here:
this.state.update((state) => ({ ...state, checklistItems: [ ...state.checklistItems, { ...checklistItem.item, id: Date.now().toString(), checklistId: checklistItem.checklistId, checked: false, }, ], }))
We are trying to update the checklistItems
state. This service will contain an
array of all items for all checklists. We add a checklistId
to each
item to tell which checklist it belongs to.
When updating our state, we first copy all of the existing checklistItems
into
the new array:
...state.checklistItems,
Thanks for checking out the preview of this lesson!
You do not have the appropriate membership to view the full lesson. If you would like full access to this module you can view membership options (or log in if you are already have an appropriate membership).