3

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)
          ]
        }
      })
    );
  }
Joseph
  • 7,042
  • 23
  • 83
  • 181
  • Updates to the state should be [immutable'ish](https://www.ngxs.io/concepts/state#actions-with-a-payload), instead of directly updating data, as you do with `is_liked` property – Yurii Nov 24 '19 at 09:27
  • 1
    @Yurii. Can you help me out? Can you edit my stackblitz? Thanks – Joseph Nov 24 '19 at 10:44

3 Answers3

3

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

Community
  • 1
  • 1
1

I'm new to NGXS but I was able to do this by playing with the built-in operators. At this stage I do not believe adding immutability tooling, like Immer, is needed.

Here is what my data looks like:

const jobs = [
  {
    id: 0,
    tasks: [
      {
        id: 0,
        status: 'To Do',
        ...
      }
  ... 
  }
]

Here is the action that updates the nested object:

  @Action(SetJob)
  setTask(ctx: StateContext<JobsStateModel>, { payload }: SetJob) {
    ctx.setState(
      patch({
        jobs: updateItem((item: any) => item.status === payload.status, patch({ tasks: insertItem(payload, 1) })),
      })
    );
  }
Ben Racicot
  • 5,332
  • 12
  • 66
  • 130
-1

you can handle the 'like' function as follows.

ctx.setState(
      patch({
        post: {
          ...state.post,
          comments: this.getUpdatedComments(state, payload)
        }
      })
    );

getUpdatedComments(state, payload): any {
      let comments = [];
      state.post.comments.forEach((cmt) => {
          if (cmt.id === payload.id) {
              cmt = Object.assign({}, cmt);
              cmt.is_liked = payload.is_liked === 1 ? 0 : 1;
          }
          comments.push(cmt);
      });
      return comments;
  }

Here is the updated demo - https://stackblitz.com/edit/ngxs-delete-like-dek3s1.

Allabakash
  • 1,969
  • 1
  • 9
  • 15
  • Thanks for this but your mutating the state. Can you revise it by not mutating the state and by using the State Operators by NGXS? Thanks – Joseph Nov 24 '19 at 12:33