1

I have the code as below which changes the values of cords inside the state if the device location is available.

class App extends Component{
  state={
    cords:{
      longitude:24.01,
      latitude:38.22
    },
    data:{}
  }
  componentDidMount() {
    console.log("Mounted")
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(position=>{
      let newCords={
        latitude: position.coords.latitude,
        longitude: position.coords.longitude
      }
      this.setState({cords:newCords});
      console.log("Inside",this.state);//displays new values
    });
    };
    console.log(this.state);// displays old values

The change in state() can be observed only inside the arrow function. How to get the changed values outside the whole if-block?

Alok Mali
  • 2,821
  • 2
  • 16
  • 32
Bimarsha Khanal
  • 300
  • 2
  • 14
  • 1
    this answer might help you https://stackoverflow.com/a/30783011/8240417 – Arif Jul 06 '20 at 05:26
  • It immediately called the console. Try to add `setTimeout`. Instead, you should use the callback function of `setState`. – Alok Mali Jul 06 '20 at 05:26

3 Answers3

0

Since setState is async, so, you will get the updated values inside callback function of state only i.e. arrow function of state in this case. Since navigator.geolocation.getCurrentPosition is an async function, that even does not returns Promise. So, once you execute this, the code further moves on to execute further lines of code, but by this time the response of navigator.geolocation.getCurrentPosition has not come, and since this time the state and cords are also not set. So, you will never be getting the coords value outside that if statement, until your API call navigator.geolocation.getCurrentPosition succeeds. Once that gets success, than the code that you have written inside its call back i.e. written below executes.

let newCords={
        latitude: position.coords.latitude,
        longitude: position.coords.longitude
      }
      this.setState({cords:newCords});
      console.log("Inside",this.state);//displays new values

So, this is how your code is working. Probably, you need to change your logic. Since navigator.geolocation.getCurrentPosition is also not returning promise so, you can't await also. Although, its not recommended, but you can setTimeOut for sometime blindly, by the time response comes like below

 componentDidMount() {
    console.log("Mounted")
    if (navigator.geolocation) {
      navigator.geolocation.getCurrentPosition(position=>{
      let newCords={
        latitude: position.coords.latitude,
        longitude: position.coords.longitude
      }
      this.setState({cords:newCords});
      console.log("Inside",this.state);//displays new values
    });
    };
    setTimeout(() => {
      console.log(this.state);
    }, 3000);
    
Raghvender Kataria
  • 1,457
  • 7
  • 14
0

I think @Anarno's answer is correct. I don't know why is it downvoted. The function from navigator is async and before it mutates the state, you are trying to log the state outside the if, it will give you the old value for sure and I am not able to relate what is the logging for, you will get the state value updated. Use React-tools instead of console loggers to see how your state changes.

spurohit
  • 15
  • 9
0

you can use temp variables to get the values outside the if block it can be used in following way

componentDidMount() {
let temp={}
console.log("Mounted")
if (navigator.geolocation) {
  navigator.geolocation.getCurrentPosition(position=>{
  let newCords={
    latitude: position.coords.latitude,
    longitude: position.coords.longitude
  }
temp=newCords;
  this.setState({cords:newCords});
  console.log("Inside",this.state);//displays new values
});
};
console.log(this.state);
console.log('temp variable having new data',temp)
}
Pavan Kalyan
  • 377
  • 1
  • 10