Changing object value in object with nested arrays of objects (infinite scroll)

Viewed 63

The original data (old) looks like this:

Object {
"pageParams": Array [
undefined,

 ],
  "pages": Array [
    Object {
      "cursor": 0,
      "items": Array [
        Object {
          "content": "This is a users post!",
          "createdAt": "2022-09-03T02:37:10.287Z",
          "id": "93d13314-630e-4948-94a4-f75677afa7ba",
          "likeCount": 10,
          "likedByUser": false,
...

Just need to toggle likedByUser on click. passing in (id,performerId) in flatlist onclick. Trying to map like this but I don't believe it is returning the original structure for the infinite scroll. need to return old with one changed object.

const likeHandler = (id: string, performerId: string) => {
    const LikePostMutation: LikePostInput = {
        id: id,
        performerProfileId: performerId,
    }
    mutateLikes.mutateAsync(LikePostMutation).then(() => {
        context.setQueryData(['fan.performer.getPostsFeed', {}], (old) => {
            if (!old) return old
            return old.pages.map((item: { items: any[] }) =>{
              item?.items.map((item) => {
                    if (item?.id === id) {
                        let newItem = {
                            ...item,
                            likedByUser: !item.likedByUser,
                        }
                        return { newItem }
                    }
                }),
            }
            )
        })
    })
}

The error message TypeError: undefined is not an object (evaluating 'o[Symbol.iterator]') is from flatlist. I think the error message coming from view:

This is the shape of logged data after mapping incorrectly: I need it to be in the pages array and in an outer object.

 }
    Object {
    content": "This is a users post!",
              "createdAt": "2022-09-03T02:37:10.287Z",
              "id": "93d13314-630e-4948-94a4-f75677afa7ba",
              "likeCount": 10,
              "likedByUser": true,
    ...

open to any suggestions on how to get better at this.

1 Answers

when doing immutable updates to arrays, you need to map over each item and return the same structure. infinite query structure is nested so it gets a bit boilerplat-y, but this should work:

context.setQueryData(['fan.performer.getPostsFeed', {}], (old) => {
  if (!old) return old
  return {
    ...old,
    pages: old.pages.map(page) => ({
      ...page,
      items: page.items.map((item) => {
        if (item?.id === id) {
          return {
            ...item,
            likedByUser: !item.likedByUser,
          }
          return item
        }
      })
    })
  }
})

if you don't like the deep spreading, take a look at immer

Related