Editing a post in React?

So, I’m not sure what is happening here. It seems to edit the index preceding the one I click.

If I click on ID 3 to edit it, it will edit ID 2. indexToEdit logs out as 1, and id logs out as 2.

Any guidance would help!

  const editArt = async (id, title, year, medium, url) => {
    const artBody = {
      title: title,
      year: year,
      medium: medium,
      poster: url
    }

    let newList = artList.slice()
    let indexToEdit = newList.findIndex(art => art.id === id)
    console.log(indexToEdit, id)
  
    let response = await fetch(`${API}/chizetteart/${id}`, {
      method: "PUT",
      mode: "cors",
      body: JSON.stringify(artBody),
      headers: {
        "Accept": "application/JSON",
        "Content-Type": "application/json",
        "token": token
      },
    })
    if (response.status !== 200) {
      alert(`Unable to edit this masterpiece!`)
    } else {
      alert(`Edited this masterpiece!`)
    }
    newList.splice(indexToEdit, 1, {id, ...artBody})
    setArtList(newList)
  }

Even if I do let indexToEdit = newList.findIndex(art => art.id === id + 1), it will edit the right one, but on the page refresh, it will edit the one before it?!

Okay, so it seems like the ID is reading the index of the array, being 0, and reading the one before it. What’s the best way to go about this?

1 Like

Not a direct answer, more of an aside.

You can tell the engine how to do its job, or you can tell it what you want it to do for you. Your code is telling the js engine how to do its job. Wouldn’t something like artList.map(...) give better results?

// this replaces the splices, and merges the new record in place
const newList = artList.map( art => (art.id == id) ? {id, ...artBody} : art );

Doing this, I don’t need to know its position in the array, I don’t care how it handles the merge, I just find the one with the matching id, and insert my updated values in place. Boom done.

just my two cents.

1 Like

Geez, humbled everyday. You’re the man.

Oh, however, I still have the problem with the ID.

How is id reading the index of the array? id is being passed into your function. I’m assuming you’re calling that from some sort of listener, where is it getting the value it passes in as a param? Are you using the index of the row, or are you saving the art.id as (for example) a data-artid attribute on an HTML element?

Honestly, I’m not sure. It is on an event listener. This is my declared function:

  const editArt = async (id, title, year, medium, url) => {
    const artBody = {
      title: title,
      year: year,
      medium: medium,
      poster: url
    }

    let newList = artList.map( art => (art.id === id) ? {id, ...artBody} : art )
  
    let response = await fetch(`${API}/chizetteart/${id}`, {
      method: "PUT",
      mode: "cors",
      body: JSON.stringify(artBody),
      headers: {
        "Accept": "application/JSON",
        "Content-Type": "application/json",
        "token": token
      },
    })
    if (response.status !== 200) {
      alert(`Unable to edit this masterpiece!`)
    } else {
      alert(`Edited this masterpiece!`)
    }

    setArtList(newList)
  }

And here is where it is passed down through props:

  const editSubmit = () => {
    editArt(id, title, year, medium, url)
    setTitle('')
    setYear(0)
    setMedium('')
    setUrl('')
  }

Calling it on a submit on a form:

 <form 
    onSubmit={e => {
      e.preventDefault()
      editSubmit(e)
    }}
 >

I am passing down from App, to a component ‘ArtList’ that is mapping over the state array, so I believe that is where it is reading the index.

export default function ArtList({ artList, editArt, deleteArt, token }) {

  // Differing CSS classes to unalign CSS Grid columns
  const columnCheck = () => {
    let column = ''
    return artList.map(
      (art, idx) => {
        switch (column) {
          case 'first':
            column = 'second'
            break
          case 'second':
            column = 'third'
            break
          default:
            column = 'first'
            break
        }
        return (
          <div
            key={idx}
            className={column}
          >
            <Art
              art={art}
              id={idx}
              artList={artList}
              editArt={editArt}
              deleteArt={deleteArt}
              token={token}
            />
          </div>
        )
      }
    )
  }

  return (
    <div className="Artlist">
      <div className="wrapper">
        { columnCheck() }
      </div>
    </div>
  )
}

And this is what I have going on in the React tools.
Screen Shot 2020-01-17 at 9.16.15 AM

@snowmonkey, very sorry to spam, but I found the issue looking through the React tools at the props. Found the id was set to 0 on the Art component. Instead of passing it through as id={idx}, I changed to id={art.id} and it works! Thank you so much for your second reply. I read it 5 more times then tackled it. Thank you!

1 Like

Perfect! Great catch, and that’s exactly what I was wondering. Solid detective work on your part. :wink:

In future, if you find you’re stuck on a bigger project like this, it might be useful to link to the repository. I will often import repositories to repl, in order to test and debug (or, if they’re bigger and need things like a db, I pull them into my dev machine). But either way, seeing the full code is almost always a good thing.

Best of luck, and send me the link when you get it done!

ps. I noticed you’re using the map I showed you, how’s it working? Should be side-effect-less, so in theory, changing that becomes transparent.

Definitely! This is the site: chizetteart.com

However, I am in the process on a new branch (been a week and a half at least) integrating hooks, cleaning up the code entirely. There is a lot of mobile styling issues, etc. Bad code from a year ago. I’ll show repo when I’m done! I would really like input from you for how to even clean it up further when I am finished.

I am currently making a new thread for a question to switch this code over to hooks and losing my mind:

  componentDidUpdate() {
    window.scrollTo(0, 1)
  }

Thank you once again for everything.