Overwrite specific JSON values but keep the ones that aren't overwritten

67 Views Asked by At

I'm currently working on an application where I receive data from server-sent-events. the data stream sends everything once in the beginning and updates only the fields that need to be updated. My question is how I can save both the original JSON object and update only the updated items.

At this moment, all items are updated. For example, if I receive a standard JSON object with 2 items {color: "black", id: 0} and I receive the following update { id: 1 }, the object is as follows {color: "", id: 1} So the object is overwritten by an empty item because it was not there.

const [initialUserData, setInitialUserData] = useState({
  id: 1,
  name: 'Pol',
  color: 'black',
});

useEffect(() => {
  const unsubscribe = sse.subscribe('playerupdate', (d: any) => {
    const receivedData = d;
    const updatedUserData = { ...initialUserData, ...receivedData }; // Create a copy of initialUserData

    // Iterate over the keys in receivedData and update updatedUserData
    for (const key in receivedData) {
      if (receivedData.hasOwnProperty(key)) {
        updatedUserData[key] = receivedData[key];
        console.log(key);
      }
    }

    updateUserData(updatedUserData);

    if (updatedUserData.PlayerId > 0) {
      setSessionState(true);
    } else if (updatedUserData.PlayerId === 0) {
      setSessionState(false);
    }
  });

  return unsubscribe;
}, []);

I am using ReactJs Context API, which is new to me, but it doesn't seem to be an issue since it updates perfectly.

2

There are 2 best solutions below

0
Thomasino73 On BEST ANSWER

I fixed it by making a normal let variable instead of a useState and updating it once. From then on the updatedUserData receives updates and puts both the variables together!

    let initialUserData = {
       id: 1,
      name: 'Pol',
      color: 'black'
    };

    useEffect(() => {
      const unsubscribe = sse.subscribe('playerupdate', (receivedData: any) => {
        if (receivedData.color === "white") {
          initialUserData = receivedData
        }

        const data = { ...initialUserData, ...receivedData };
        updateUserData(data);

        setSessionState(data.PlayerId > 0);
      return unsubscribe;
    }, []);

6
AmerllicA On

Take a look at my edition:

const [initialUserData, setInitialUserData] = useState({
  id: 1,
  name: 'Pol',
  color: 'black',
});

useEffect(() => {
  const unsubscribe = sse.subscribe('playerupdate', (receivedData: any) => {
    // Merge the receivedData into the initialUserData
    const updatedUserData = { ...initialUserData, ...receivedData };

    updateUserData(updatedUserData);

    setSessionState(updatedUserData.PlayerId > 0);
  });

  return unsubscribe;
}, []);

You don't need that for in loop. And I added another correction in the setSessionState. There is no need to add tons of codes when the value is boolean, and you can directly use them instead of using if-then else.