3d cartoon hands holding a phone

Unlock full course by purchasing a membership

Lesson 12

Editing and Deleting Data

STANDARD

Editing and Deleting Data

The last key feature we need to focus on is the ability to edit and delete the checklists and checklist items. This will involve a reasonably simple extension in terms of the functionality in our services.

Update the Services

We will start by adding support for editing and deleting items in the ChecklistItemService. This is by no means easy or obvious, but this will serve well as an opportunity to implement a slightly more advanced feature with no guidance.

Before continuing, see if you can add new sources and reducers that allow deleting and editing specific checklist items. We have already created the appropriate types for EditChecklistItem and RemoveChecklistItem so you can use these as reference for the type of data you will be working with.

See how much progress you can make on this and then take a look at my solution below (don’t worry if you get stuck).

Add the following sources to ChecklistItemService:

  remove$ = new Subject<RemoveChecklistItem>();
  edit$ = new Subject<EditChecklistItem>();

Add the following reducers to ChecklistItemService:

    this.edit$.pipe(takeUntilDestroyed()).subscribe((update) =>
      this.state.update((state) => ({
        ...state,
        checklistItems: state.checklistItems.map((item) =>
          item.id === update.id ? { ...item, title: update.data.title } : item
        ),
      }))
    );

    this.remove$.pipe(takeUntilDestroyed()).subscribe((id) =>
      this.state.update((state) => ({
        ...state,
        checklistItems: state.checklistItems.filter((item) => item.id !== id),
      }))
    );

That’s all we need to do — we can now next the edit$ and remove$ sources to edit or remove checklist items.

Now we want to handle removing and editing checklists in the ChecklistService… but we have a bit of a surprise in store first.

Consider that if we want to remove a checklist, we will also want to remove all of the checklist items for that checklist. That means that our ChecklistItemService is going to need to know when the removal of a checklist is triggered, so that it can handle removing all of the items related to that checklist.

To handle this, we are going to create a shared source. We are actually going to add a checklistRemoved$ source to our ChecklistItemService. Our ChecklistItemService will react to that by removing all of the items. Then, in our ChecklistService we will use the same checklistRemoved$ source from ChecklistItemService and the ChecklistService will react to that same source emitting by removing the appropriate checklist. When we trigger the checklistRemoved$ source in the ChecklistItemService both our ChecklistItemService and our ChecklistService will automatically react (just in different ways).

Add the following source to the ChecklistItemService:

checklistRemoved$ = new Subject<RemoveChecklist>();

Add the following reducer to the ChecklistItemService:

    this.checklistRemoved$.pipe(takeUntilDestroyed()).subscribe((checklistId) =>
      this.state.update((state) => ({
        ...state,
        checklistItems: state.checklistItems.filter(
          (item) => item.checklistId !== checklistId
        ),
      }))
    );

Now when the checklistRemoved$ source emits we will remove all of the items for that checklistId.

Now we will utilise this same checklistRemoved$ source in our ChecklistService.

Add the following source to the ChecklistService:

  remove$ = this.checklistItemService.checklistRemoved$;

Now we inject the ChecklistItemService and utilise the same source for the removal in the ChecklistService. This is better than having two separate sources in each service, because we would need to make sure we trigger the sources in both services whenever we want to remove a checklist. This way, we can just trigger the one shared source.

We also need a source to handle editing in the ChecklistService as well.

Add the following source to the ChecklistService:

  edit$ = new Subject<EditChecklist>();

Add the following reducers to the ChecklistService:

    this.remove$.pipe(takeUntilDestroyed()).subscribe((id) =>
      this.state.update((state) => ({
        ...state,
        checklists: state.checklists.filter((checklist) => checklist.id !== id),
      }))
    );

    this.edit$.pipe(takeUntilDestroyed()).subscribe((update) =>
      this.state.update((state) => ({
        ...state,
        checklists: state.checklists.map((checklist) =>
          checklist.id === update.id
            ? { ...checklist, title: update.data.title }
            : checklist
        ),
      }))
    );
STANDARD
Key

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