0

Trying to change the value of one object within an array when I perform an image upload.

Image is coming from a child component with an identifying name, then I loop through the array (stored in state) and try to replace the corresponding object's image prop. Also attempted with a forEach.

I've tried all of the solutions on this answer and this answer, but sadly getting no where.

Here are my two latest attempts:

handleImageUpload = (data) => {

// method 1
    for (let i = 0; i <= this.state.artists.length; i++) {
      console.log(data);
      if (this.state.artists[i].artist === data.artist) {
        let artists = [...this.state.artists];
        let newArtistEdit = {
          name: data.name,
          image: data.image,
        };
        artists[i] = newArtistEdit;
        this.setState({ artists });
      } else return;
    }


// method 2, using immutability helper
    for (let i = 0; i <= this.state.artists.length; i += 1) {
      try {
        if (this.state.artists[i].artist === data.artist) {
          this.setState((prevState) => ({
            artists: update(this.state.artists, {
              i: { image: { $set: data.image } },
            }),
          }));
        }
      } catch (error) {
        console.log(error.message);
      }
    }

};

Any ideas why the image prop for artist[i] is never getting updated?

For reference: method 1 doesn't update anything, and method 2 adds a new state property called 'null', containing the image.

crevulus
  • 1,658
  • 12
  • 42
  • Can you show us your `artists` state? – bertdida Aug 20 '20 at 13:37
  • Doesn't each `artist` don't have an `id`? Can't you do `artists[i].artist.id === data.artist.id`? – bertdida Aug 20 '20 at 13:42
  • in App.js it's literally just: state = { artists: [], } Then when it's updated by new input, it becomes: artists: [ {artist: 'foo fighters', image: null} {artist: 'the who', image: null} ] I set image to null by default, and no there's no id for each but shouldn't be necessary as I'm matching artists on names. – crevulus Aug 20 '20 at 13:42
  • And what's the value of `data` argument would look like? – bertdida Aug 20 '20 at 13:52
  • This is from the child component: `onImageUpload = (e) => { const artistInfo = { artist: this.props.match.params.artistName, image: e.target.value, }; this.props.onImageUpload(artistInfo); }; ` The event is a file upload. – crevulus Aug 20 '20 at 14:00
  • 1
    Hmmm maybe are you looking something like [this](https://codesandbox.io/s/summer-voice-onig8?file=/index.html)? – bertdida Aug 20 '20 at 14:02
  • oh my god you legend, this worked. But why does it work? As far as I can tell it's checking current artist name vs data's artist name - that's understandable. But how does simply writing `return { ...currArtist, ...data }` end up replacing the image prop? – crevulus Aug 21 '20 at 07:03
  • 1
    I'm merging the objects using `spread operator`. Whatever property on `currArtist` will be replaced by the property on `data`, given that they have the same name. – bertdida Aug 21 '20 at 07:13

0 Answers0