robdigm
robdigm

Reputation: 143

How to do multiple dispatches in component with one set state?

I have a component which has to do multiple dispatches in a componentDidMount but I want to set the state once. Is there a way to do this efficiently once for only one page render?

componentDidMount() {
        this.setState({ fetchInProgress: true });      
        this.props.getJobs(null, null) 
            .then((res) => {
                if (res.results.response.length > 0){
                var initStart = res.results.response[0].ID;
                var initEnd = res.results.response[res.results.response.length - 1].ID;
                var newStart = initStart;
                var newEnd = initEnd;
                var snewStart = null;
                var snewEnd = null;
                var sinitStart = null;
                var sinitEnd = null;
                var filterOn = false;
                var searchOn = false;
                var pagMax = (Math.ceil(res.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length) / 10 : 0;
                pagMax = pagMax + 1;
                    this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, filterOn, searchOn});
                }   
                this.setState({
                    fetchInProgress: false,
                    panelOpen:false,
                    data: res.results.response || []
                })
            });
        this.props.getJobNames()
            .then((res) => {                
                this.setState({                    
                    jobNames: res.results.response || []
                })
            });
    }

The expected result is to have the page rendered once rather than twice.

Upvotes: 0

Views: 72

Answers (1)

Devin Cenatiempo
Devin Cenatiempo

Reputation: 142

Yes, there is a way to solve this issue using Promise.all() which allows you to return one promise from multiple promises. The returned promise is an array of resolved promises in the same order as the arguments.

I'm using array destructuring to access the values in the example code, but you could just resolve to res and then access the values with res[0] and res[1] if you wanted.

An example of how to use this in your code might be:

componentDidMount() {
  this.setState({ fetchInProgress: true });      
  const getJobsPromise = this.props.getJobs(null, null);
  const getJobNamesPromise = this.props.getJobNames();

  Promise.all([getJobsPromise, getJobNamesPromise])
    .then(([jobsRes, jobNamesRes]) => {
      if (jobsRes.results.response.length > 0){
      var initStart = jobsRes.results.response[0].ID;
      var initEnd = jobsRe.results.response[jobsRe.results.response.length - 1].ID;
      var newStart = initStart;
      var newEnd = initEnd;
      var snewStart = null;
      var snewEnd = null;
      var sinitStart = null;
      var sinitEnd = null;
      var filterOn = false;
      var searchOn = false;
      var pagMax = (Math.ceil(jobsRes.results.response.length / 10) > 0) ? Math.ceil(res.results.response.length) / 10 : 0;
      pagMax = pagMax + 1;
        this.props.dispatch({ type: jobConstants.JOB_SUCCESS, newStart, newEnd, initStart, initEnd, pagMax, snewStart, snewEnd, sinitStart, sinitEnd, filterOn, searchOn});
      }   
      this.setState({
        // from getJobsPromise
        fetchInProgress: false,
        panelOpen:false,
        data: res.results.response || [],
        // from getJobNamesPromise
        jobNames: jobNamesRes.results.response || [],
      });
    });
}

See MDN docs on Promise.all() https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

Upvotes: 1

Related Questions