Here’s my situation:
- on this.handleFormSubmit() I am executing this.setState()
- inside this.handleFormSubmit(), I am calling this.findRoutes(); – which depends on the successful completion of this.setState()
- this.setState(); does not complete before this.findRoutes is called…
- How do I wait for this.setState() inside of this.handleFormSubmit() to finish before calling this.findRoutes()?
A subpar solution:
- putting this.findRoutes() in componentDidUpdate()
- this is not acceptable because there will be more state changes unrelated the findRoutes() function. I don’t want to trigger the findRoutes() function when unrelated state is updated.
Please see code snippet below:
handleFormSubmit: function(input){ // Form Input this.setState({ originId: input.originId, destinationId: input.destinationId, radius: input.radius, search: input.search }) this.findRoutes(); }, handleMapRender: function(map){ // Intialized Google Map directionsDisplay = new google.maps.DirectionsRenderer(); directionsService = new google.maps.DirectionsService(); this.setState({map: map}); placesService = new google.maps.places.PlacesService(map); directionsDisplay.setMap(map); }, findRoutes: function(){ var me = this; if (!this.state.originId || !this.state.destinationId) { alert("findRoutes!"); return; } var p1 = new Promise(function(resolve, reject) { directionsService.route({ origin: {'placeId': me.state.originId}, destination: {'placeId': me.state.destinationId}, travelMode: me.state.travelMode }, function(response, status){ if (status === google.maps.DirectionsStatus.OK) { // me.response = response; directionsDisplay.setDirections(response); resolve(response); } else { window.alert('Directions config failed due to ' + status); } }); }); return p1 }, render: function() { return ( <div className="MapControl"> <h1>Search</h1> <MapForm onFormSubmit={this.handleFormSubmit} map={this.state.map}/> <GMap setMapState={this.handleMapRender} originId= {this.state.originId} destinationId= {this.state.destinationId} radius= {this.state.radius} search= {this.state.search}/> </div> ); } });
Advertisement
Answer
setState()
has an optional callback parameter that you can use for this. You only need to change your code slightly, to this:
// Form Input this.setState( { originId: input.originId, destinationId: input.destinationId, radius: input.radius, search: input.search }, this.findRoutes // here is where you put the callback );
Notice the call to findRoutes
is now inside the setState()
call,
as the second parameter.
Without ()
because you are passing the function.