Search code examples
react-nativeamazon-s3thissetstateaws-amplify

Can't access this.setState inside 2nd API call in nested calls (AWS Amplify Storage API) (React Native)


  • The first call (Storage.list('s3 bucket path')) returns a list of keys.
  • For each key, I make a second call (Storage.get('key')) that returns a url
  • Inside the first AND second API call I console.log and get the correct data I need for each.
  • this.setState works perfectly inside the first API call, but it doesn't inside the second one.

My code is:

    state = { keyItems: [], urlItems: [] }

    componentDidMount() {
        Storage.list('')
          .then(keyItems => {
            console.log("keyItems: ", keyItems)
            this.setState({ keyItems: keyItems })

            /*for each photo key in the folder..*/
            keyItems.forEach(function(keyItem) {
              /*get the URL*/
              Storage.get(keyItem.key)
                .then(urlItem => {
                  console.log("urlItem: ", urlItem)
                  /*add URL item to state*/
                  /*ANY CALL TO this.setState HERE DOESN'T WORK, i've tried 
                  even simple tests*/
                  this.setState(prevState => ({ urlItems:[...prevState.urlItems, { key: keyItem.key, source: urlItem } ]}))
                })
                .catch(err => {
                  console.log("error fetching photo URL", err)
                })
            })
          })
          .catch(err => {
            console.log("error fetching photos keys", err)
          })
      }

Console: Console

  • I've tried making the calls from arrow functions outside the componentDidMount but still can't access the this.setState

Thanks!


Solution

  • The value of this is getting lost inside the .then

    You could try this

    1. Set this to a variable
    2. Use that variable instead of this

    Here it in code

    componentDidMount () {
      const that = this;
    
      // now call setState like this
      that.setState(...)
    
    }
    

    You can read more about it at the link below, but I’ve put the general gist of it here.

    this is always the object the method is called on. However, when passing the method to then(), you are not calling it! The method will be stored somewhere and called from there later.

    Why is 'this' undefined inside class method when using promises?