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).