ReactRouter4
ReactRouter4

Reputation: 165

setstate then response in rest api react

I would like to make the state isLoading changed to true when recentTransactionsRecipient and recentTransactionsSender is not null.

I would like to do a promise, then

  componentDidMount() {
    this.Auth.recentTransactionsRecipient(this.props.id)
      .then(res => {
        if (res) {
          this.setState({
            recentTransactionsRecipient: res,
          });
        }
      })
      .catch(() => {
        /* just ignore */
      });

    this.Auth.recentTransactionsSender(this.props.id)
      .then(res => {
        if (res) {
          this.setState({
            recentTransactionsSender: res,
          });
        }
      })
      .catch(() => {
        /* just ignore */
      });
  }

Upvotes: 0

Views: 151

Answers (2)

Dacre Denny
Dacre Denny

Reputation: 30360

The use of Promise.all() would work well here as it allows you to reduce multiple input promises into a single promise. The single promise returned by Promise.all() is where you would implement the isLoading : true state update logic for your component.

An important detail to note with this; Given your code requires any errors in Auth to be ignored (coupled with the behavior of Promise.all() to reject if any promise passed to it is rejected), you will need to account for this in your code.

One possibility is to introduce a helper function that would "absorb" a rejected promise so that the rejected promise isn't propagated to Promise.all() (which would cause your subsequent setState() to be skipped):

componentDidMount() {
    
    /*
    Locally defined helper method to absorb failure/rejection of the supplied promise
    */
    const ignoreIfRejected = (promise) => {
      
      return promise().catch(() => {
        console.info('A promise failed. Ignoring.');
      });
    }
    
    /* 
    The Promise returned from Promise.all will reject if any one of the promises in
    the passed array fails. Wrap each promise in locally defined ignoreIfRejected()
    helper to "absorb" any such error 
    */
    Promise.all([
      ignoreIfRejected(this.Auth.recentTransactionsRecipient(this.props.id)),
      ignoreIfRejected(this.Auth.recentTransactionsSender(this.props.id))
    ])
    .then((recipient, sender) => {
      
      if( recipient !== null && sender !== null) {
        
        /* 
        If resolved response from both promises returns non-null value
        then set isLoading state to true as required in post 
        */
        this.setState({ 
          recentTransactionsSender : sender,
          recentTransactionsRecipient : recipient,
          isLoading : false 
        });
      }      
    });
  }

Upvotes: 0

mehamasum
mehamasum

Reputation: 5732

Try using Promise.all(). See MDN doc

The Promise.all() method returns a single Promise that resolves when all of the promises passed as an iterable have resolved or when the iterable contains no promises. It rejects with the reason of the first promise that rejects.

Promise.all([promise1, promise2]).then((values) => {
  console.log(values);
  this.setState({
    recentTransactionsRecipient: values[0],
    recentTransactionsSender: values[1],
    isLoading: false
  });
});

Upvotes: 2

Related Questions