0
votes

So here's my problem, I have a react native app I'm working on right now, all of the code works except for the function getLocation(). It works in the sense that it returns a latitude and longitude but for some reason it takes too long and when I run a function that relies on the values, it doesn't run in time when that function is called. Is there any way I could maybe delay the function so it has the latitude and longitude when the getLocation() function returns it?

I did some prior research and this was another stack overflow question that is kind of similar, however they used a different way of getting the location. React native setting/accessing a variable inside a function

Any help would be appreciated!

import React, { Component } from 'react';
import { ActivityIndicator, ListView, Text, View, Picker } from 'react-native';

export default class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            isLoading: true,
            dataSource: null,
            key: "KEY NOT SHOWN BUT WORKS",
            latitude: null,
            longitude: null,
            error: 2
        };
    }


    /**
     * This function gets the current geo location of the device and stores it
     * as Lat and Long coordinates.
     * @private
     */
    getLocation(){
        navigator.geolocation.getCurrentPosition(
            (position) => {
                this.setState({
                    latitude: position.coords.latitude,
                    longitude: position.coords.longitude,
                });
            },
            (error) =>
                this.setState({ error: error.message, latitude: 41.77, longitude: -88.07,}),
            { enableHighAccuracy: false, timeout: 5000, maximumAge: 10000 },
        );
    }

    getAPI(){
        fetch('https://developer.cumtd.com/api/v2.2/JSON/getstopsbylatlon?key='+this.state.key+'&lat='+this.state.latitude.toString()+'&lon='+this.state.longitude.toString())
            .then((response) => response.json())
            .then((responseJson) => {
                this.setState({
                    dataSource: responseJson.stops,
                    isLoading: false,
                }, function() {
                    // do something with new state
                });
            })
            .catch((error) => {
                //error
            });
    }

    componentDidMount() {
        this.getLocation();
        this.getAPI();
    }



    render() {
        if (this.state.isLoading) {
            return (
                <View style={{flex: 1, paddingTop: 20}}>
                    <ActivityIndicator />
                </View>
            );
        }
        return (
            <View style={{flex: 1, paddingTop: 20}}>
                <Text>Latitude: {this.state.latitude}</Text>
                <Text>Longitude: {this.state.longitude}</Text>
                <Picker
                    selectedValue={this.state.dataSource}>
                    {this.state.dataSource.map((item, key)=>(
                        <Picker.Item label={item.stop_name} value={item.stop_name} key={key}/>))}
                </Picker>
            </View>
        );
    }
}
1
The geolocation API is asynchronous, so you'll have to find a way to handle things when that info isn't available yet. There isn't really a way to make it any faster. Moreover, it's very possible that the user denies the location permission request, in which case you'll never get the lat/long. So you may as well embrace it and figure out something to display when the lat/long isn't available. - CRice
Thank you for the quick reply! I was thinking and thought making a boolean and just have it set to true when it changes the value but then I'd need a loop checking it constantly. Is there a more efficient way to do that? - Pradeep
It returns a value when the success callback you give to getCurrentPosition executes. So you'll need to put dependent code within that callback, OR, you could wrap the getCurrentPosition call so that it returns a promise, then use the promise .then method. But either way you have to embrace the asynchronicity of it. - CRice
That makes sense! Thanks! - Pradeep

1 Answers

3
votes

Here is a snack with a proposed solution

Simply move the API call into the getLocation(), after the location has been retrieved. You will want to move towards a more Promise based structure when you integrate Permission handling. 😄