ashishsanjayrao
ashishsanjayrao

Reputation: 101

React - Unable to setState inside a Promise then

I'm trying to set the state inside a then() of a Promise, but the state value is not getting saved and is not accessible outside of the then().

Below is the UPDATED code:

handleSelect = location => {
  this.setState({ location });
  geocodeByAddress(
    location
  )
  .then(results => getLatLng(results[0]))
  .then(latLng => {
    this.setState({
      location_latitude: latLng.lat,
      location_longitude: latLng.lng,
    })
    console.log(this.state.location_latitude); // returns the correct value
  })
  console.log(this.state.location_latitude); // returns null (the originally declared value)
}

If I console.log(this.state.location_latitude) I get a null value. But if I console.log inside the then() block, I get the correct value. How do I set the state in this case?

UPDATED explanation:

To give a better context to the whole logic here: I'm using a Google Places Autocomplete component which allows the user to select a location from the dropdown. The above method handleSelect is called when the user selects a location from the dropdown. I then extract the latitude and longitude of the place selected by the user using the geocodeByAddress method, which is a promise. I need to then retrieve the latitude and longitude and set the state accordingly, which is later used to send to the database. I can't submit the value to the database yet because there are other form inputs that the user needs to fill (which are also stored in the state) and once he clicks on Submit, I'll be submitting all the state elements in a single call to the backend. So, there is nothing I want to update with componentDidMount() or nothing is getting updated yet to use componentDidUpdate(). In any case, I can only store the state value inside the then of geocodeByAddress (please correct me if I'm wrong here). So, I HAVE to be able to modify the state value inside the then block.

Upvotes: 0

Views: 2788

Answers (3)

Afsanefda
Afsanefda

Reputation: 3339

The thing is when you set-state you can't see the state result immediately after that. That's why the console.log returns null. Make sure your console.log is in the render block. This is because set-state actions are asynchronous and are batched for performance gains. This is explained in documentation of setState. Take a look at this => Why is setState in reactjs Async instead of Sync?

Upvotes: 3

Neil
Neil

Reputation: 968

This is clearly an issue with your data call not react.

Your react code looks fine but I suggest spitting the code.

1) service.js file - this does your query and returns data or returns error.

2) location component, componentDidMount() or useEffect(() => {}, []) gets the data and updates state/useState()

ā€”

To give you a code snippet I need to you to provide a console log of latLang & results.

Many thanks šŸ‘ŒšŸ»

Upvotes: -1

Atul
Atul

Reputation: 3433

You need to bind the function context to current class/ component. Try something like below. Create a function like "callSetState" bind it with this and while calling in then just pass the values as parameters to it.

import React, { Component } from 'react';
class Test extends Component{
    constructor() {
        super()
        this.callSetState = this.callSetState.bind(this);
    }

    callSetState(latitude, longitude) { 
        this.setState({
            location_latitude: latitude,
            location_longitude: longitude,
        })
    }

/* Call this func in your class and call callSetState which is already bound to your component in constructor */

    // geocodeByAddress(location)
    //     .then(results => getLatLng(results[0]))
    //     .then(latLng => this.callSetState(latLng.lat, latLng.lng));

}

Upvotes: 0

Related Questions