1

What's wrong with below code?

this.setState({
  album: {
    ...this.state.album,
    photos: [
      ...this.state.album.photos,
      { url : newUrl }
    ]
  }
})

It worked if photos have something, but if album is an empty object, I will got this error

Cannot convert undefined or null to object
1
  • @BoyWithSilverWings album is an empty object Commented Feb 2, 2018 at 7:31

3 Answers 3

3

You can also use: (...this.state.album.photos || []) so it parses the empty array at first:

const state = {
  album: {
    photos: undefined
  }
}

const newState = {
  album: {
    ...state.album,
    photos: [
      ...(state.album.photos || []),
      { url: 'newUrl' }
    ]
  }
}

console.log(newState)

Sign up to request clarification or add additional context in comments.

8 Comments

what about using Object.assign() as I have done in the answer below? Which one would be better?
IMO, there's no better solution nor right or wrong :). About differences between Object.assign and spread operator you can check this answer :)
I also answered your question based on your code sample. You were already using spread operator in it.
this is elegant, many thanks! I have to be aware of default empty arr next time doing spread!
I think better to init an empty array, it's more readable and less logic.
|
0

Yeah, that's the expected behaviour. The spread operator (...) will spread, that is, expand everything provided. If that's null, it can't possibly do that, right?

You can try something like:

...( Object.assign( {}, this.state.album.photos )

1 Comment

The ... is the spread operator. Object.assign() will give us a new object based on the photos property. If it's null, it'll be an empty object and, hence, the spread operator will do nothing. However, if it does have content, it'll just spread it normally.
0

Use Short circuit evaluation concept and put ||[] with state.albums.photos, if albums will be blank object then (photos=undefined || []) will return an empty array.

Use this:

this.setState(prevState => ({
    album: {
        ...prevState.album,
        photos: [
            (...prevState.album.photos || []),
            { url : newUrl }
        ]
    }
}))

Use updater function and prevState to compute the next state value.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.