angularangular6angular7ngxsangular-state-managmement

Access Nested Object Inside Array in Angular NGXS


I have successfully implemented the delete comment function in my Angular app. My problem now is on the liking function of the comment. How do i implement the like function. I have the variable is_liked to determine if its like or not. The value = 0 means its not like and the value = 1 is liked. Pls see my stackblitz link here

PLS CLICK THIS LINK

onLikeComment(data: Comment) {
    this.store.dispatch(new LikeComment(data)).subscribe();
  }

@Action(LikeComment)
  likeComment(
    ctx: StateContext<PostStateModel>,
    { payload }: LikeComment
  ) {
    if (payload.is_liked === 1) {
      payload.is_liked = 0;
    } else {
      payload.is_liked = 1;
    }
    const state = ctx.getState();
    ctx.setState(
      patch({
        post: {
          ...state.post,
          comments: [
            ...state.post.comments,
            updateItem<any>(name => name === payload.id, payload)
          ]
        }
      })
    );
  }

Solution

  • The main problem you have in your code is the use of the updateItem state operator. This operator needs to be assigned to the field in the object you pass to the patch operator.

    patch({
      field1: 'someValue',
      comments: updateItem<Comment>(
        comment => comment.id === 0,
        {id: 0, text: 'This is a nice post!', is_liked: 1}
      )
    })
    

    updateItem Reference

    The second problem I see with your action handler is that you're not using the patch operator correctly. This operator allows to only assign the values to the fields you want to change like StateContext.patchState.

    I would change your code to this:

      @Action(LikeComment)
      likeComment(
        ctx: StateContext<PostStateModel>,
        { payload }: LikeComment
      ) {
        const isLiked = payload.is_liked === 1 ? 0 : 1;
    
        ctx.setState(
          patch({
            // Apply patch on the post to only update the comments field
            post: patch({
              // Apply updateItem to make the operator only update the item that matches the condition
              comments: updateItem<Comment>(
                comment => comment.id === payload.id,
                // Apply a patch on the found comment to only change the is_liked field.
                patch({is_liked: isLiked}))
            })
          })
        );
      }
    

    Hope this makes sense. It's my first answer on SO :)

    Here's the updated stackblitz