Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mutate specific object in an array using SWR

I have the following array

[
{
"idChatPublic": 17,
"idChatRoom": 2,
"idSender": "6c25110d-4256-42e1-8205-b75ece274487",
"username": "Hudson Thadeu Teixeira",
"message": "hello",
"avatar": null,
"createdAt": "12:43",
"chatLike": []
},
{
"idChatPublic": 33,
"idChatRoom": 2,
"idSender": "6c25110d-4256-42e1-8205-b75ece274487",
"username": "Hudson Thadeu Teixeira",
"message": "jam",
"avatar": null,
"createdAt": "13:07",
"chatLike": [
  {
    "idChatLike": 1,
    "idChatPublic": 33,
    "idUser": "",
    "createdAt": "2022-02-14T08:59:34.000Z"
  }
 ]
}
]

How can mutate an specific object of this array and add an object to the "chatLike" array using SWR?

I have the following function:

async function sendLike() {
const newLike = {
  idUser: myUser.userId,
}

mutate(
  async (data) => {
    console.log(data[messageIndex]) // This log returns specific object in the array

    // Handle mutation

  },
  false
)
socket.emit('send_like', newLike)
}

Please guys I've been trying this for a while would be great If someone gives me a hand :D

like image 871
Diego Braga Avatar asked Nov 24 '25 23:11

Diego Braga


1 Answers

Note: As of v2.1.0, SWR now supports subscribing to real-time data sources via the useSWRSubscription hook


Old answer:

You're using SWR with a websocket, which is an anti-pattern. SWR is meant for managing data that's fetched via REST or GraphQL requests, and it can be configured to refetch data on a regular interval. It's not a real time connection. Websocket on the other hand is real time. Consider if SWR is really best for your project - you probably don't need it.

Anyway, I also noticed some issues with how your mutate() is written so here's some feedback.

  • you must pass an ID into first argument
  • if you pass a function into mutate's second argument, it must return the new data
  • an easy way to update a specific item in an array is by using .map() and spread ... syntax
function sendLike() {
  const newLike = {
    idUser: myUser.userId,
  }

  // send request to update the source
  // this is usually an REST request such as 'POST, UPDATE' etc
  socket.emit('send_like', newLike)

  // mutate local data
  mutate(
    '/api/chat', // ID must match ID used in the useSWR hook,
    data => data.map(chat => chat.idChatPublic === idChat : {
      ...chat,
      chatLike: [
        ...chat.chatLike
        newLike
      ]
    } : chat),
    false
  );
}

like image 176
Ro Milton Avatar answered Nov 26 '25 15:11

Ro Milton



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!