0

I am new to react/javascript paradigm. So i have picked up a course a freecodingcamp.org to start learning. I am currently getting an error at this implementation (https://youtu.be/kqi4gPfdVHY?list=PLmexTtcbIn_hvPcUm3oAufCtH7dwNAC-g&t=2447)

Here is the code for addLike button. The error is that when I "update" the song, the new updated songs list doesn't have all values (the size of the array is same but first element is 0). Specifically these two lines in the code

      const songData = await API.graphql(graphqlOperation(updateSong, {input: song}))
      const songList = [...songs];

Now, I am no javascript expert so i am not sure why ... syntax isn't copying the error to new array. it just copies one element and thats it. what am i doing wrong?

FULL CODE

function App() {

  const [songs, setSongs] = useState([])

  useEffect(() => {
    fetchSongs()
  }, [])

  const fetchSongs = async () => {
    try {
      const songData = await API.graphql(graphqlOperation(listSongs));
      const songList = songData.data.listSongs.items;
      console.log('song list', songList);
      setSongs(songList)
    } catch (error) {
      console.log('error on fetching songs', error)
    }
  }

  const addLike = async(idx) => {
    try {
      const song = songs[idx];
      song.like = song.like + 1;
      delete song.createdAt;
      delete song.updatedAt;
      const songData = await API.graphql(graphqlOperation(updateSong, {input: song}))
      const songList = [...songs];
      songList[idx] = songData.data.updateSongs;
      setSongs(songList);
    } catch (error) {
      console.log('error on adding like to the song', error)
    }
  }

Em Ae
  • 8,167
  • 27
  • 95
  • 162
  • 3
    [Spread syntax](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax) creates a shallow copy meaning that nested objects are not copied, but passed as references. As a result, when you change `songList[idx]` you are mutating state. See:[Deep copy in ES6 using the spread syntax](https://stackoverflow.com/questions/38416020/deep-copy-in-es6-using-the-spread-syntax) and [How to update nested state properties in React](https://stackoverflow.com/questions/43040721/how-to-update-nested-state-properties-in-react/50149659#50149659) – pilchard May 26 '21 at 16:24
  • Okay but the problem isn't if i am changing state etc. the problem is that the `songList` (the newly created one) has same size as original array but the first element is undefined hence giving me error. If i refresh the page, then it renders fine and thats because of `fetchSongs` effect – Em Ae May 26 '21 at 16:38
  • If refreshing the page, and thus resetting the state is 'fixing' it then it absolutely sounds like a state mutation problem. In fact, you are mutating it from the first line in the `try` when you directly access an element from the state array. – pilchard May 26 '21 at 16:51
  • Hmm, I could be totally wrong but if that was the case then this `adsLike` method should throw an exception. Shouldn't it ? It's not throwing any. Exception is being thrown where I am using songs to render html in loop ... And on first iteration I get exception since item 0 is null – Em Ae May 26 '21 at 19:42
  • The problem was `songList[idx] = songData.data.updateSongs` ... my operation name is `updateSong` so this line should be `songList[idx] = songData.data.updateSong` (notice no s at the end of the song). Since there was an `s`, the `songList[0]` was being set to undefined :D – Em Ae May 27 '21 at 17:55

0 Answers0