Set timer to loading component

Viewed 36

I need to load a map in a component, with a loading circle appearing while the component is loading the user location. The thing is, it works, too well indeed. What I mean, if I don't have a location (maybe because I didnt gave permission to) the loading circle appears for ever, or until a location is given.

How can I set this loading component to be in a while and after it, justo load a given coordinates?

loading component

import React from 'react';
import { CustomView as View } from '../View/View';
import { StyleSheet } from 'react-native';
import { ActivityIndicator } from 'react-native';

export const Loading = ({size, color}) => {
    return(
        <View style={styles.viewLoading}>
            <ActivityIndicator size={size} color={color} />
        </View>
    )
}

const styles = StyleSheet.create({
    viewLoading: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center'
    }
})

and this is my map component


import React, { useState, useEffect } from "react";
import { StyleSheet, Image } from "react-native";
import { Ionicons } from "@expo/vector-icons";
import MapView, { Marker, Callout } from 'react-native-maps';
import { Loading } from 'components/elements';

import * as Location from 'expo-location';

import { View, Text } from "components/elements";
import colors from "components/elements/colors";


const Map = (props) => {
    const {
        onCalloutPress,
        franchises,
    } = props;

    const [userLocation, setUserLocation] = useState(null);
    const [region, setRegion] = useState(null);
    const [selectedLocal, setSelectedLocal] = useState()
    const [loading, setLoading] = useState(true)


    useEffect(() => {
        (async () => {
            let { status } = await Location.requestForegroundPermissionsAsync();
            if (status !== 'granted') {
                return;
            }

            let location = await Location.getCurrentPositionAsync({});
            {
                setUserLocation(location) !== null
                ?
                isLoading(false)
                : {}
            }
            setRegion({
                latitude: location?.coords?.latitude,
                longitude: location?.coords?.longitude,
                latitudeDelta: 0.01,
                longitudeDelta: 0.01,
            })
        })();
    }, []);

    const isLoading = (boolean) => {
        setLoading(boolean)
    }

    if (!(region || franchises.length)) return null;

    const handleSelectLocal = (franchises) => {
        onCalloutPress(franchises)
        setSelectedLocal(franchises)
    }

    return (
        <>
        {/* TODO MAP APPEAR WHEN NO LOCATION IS FOUND AFTER A WHILE */}
            {!loading
                ?
                <MapView
                    style={styles.map}
                    zoomControlEnabled={true}
                    initialRegion={region}
                >
                    {userLocation &&
                        < Marker
                            coordinate={userLocation.coords}
                        >
                            <Image
                                source={require("components/elements/assets/Imagen_perfil.png")}
                                style={{ width: 35, height: 35 }}
                            />
                        </Marker>
                    }

                    {
                        franchises.map((stop, i) => (
                            <Marker
                                coordinate={{ latitude: Number(stop.latitude), longitude: Number(stop.longitude) }}
                                key={i}
                                onPress={() => setSelectedLocal(stop)}
                            >

                                {selectedLocal?.latitude === stop.latitude && selectedLocal?.longitude === stop.longitude ?
                                    <Image
                                        source={require("../../elements/assets/MapPin.png")}
                                        style={{ width: 41 }}
                                    /> :
                                    <Image
                                        source={require("components/elements/assets/yellowIcon.png")}
                                        style={{ width: 41, height: 41 }}
                                    />
                                }
                                <Callout
                                    tooltip
                                    onPress={e => handleSelectLocal(stop)}
                                >

                                    <View style={styles.calloutView}>
                                        <Text style={styles.calloutName}>{stop.Nombre}</Text>
                                        <Text style={styles.calloutAddress}><Ionicons name="location-outline" size={15} color="black" /> {stop.Direccion}</Text>
                                    </View>
                                </Callout>
                            </Marker>

                        ))
                    }

                </MapView >

                : <Loading size="large" color="#F5BF0D" style={ styles.loading}/>
            }
        </>
    );
};

const styles = StyleSheet.create({
    map: {
        flex: 1
    },
    loading:{
        display:"flex",
        alignContent:"center",
        alignItems:"center"
    },
    calloutView: {
        backgroundColor: colors.accent,
        paddingHorizontal: 15,
        paddingVertical: 11,
        width: 200,
        borderRadius: 5,
        marginBottom: 10,
    },
    calloutName: {
        fontFamily: 'Montserrat_700Bold',
        fontSize: 15
    },
    calloutAddress: {
        fontFamily: 'Montserrat_400Regular',
        fontSize: 15
    }
});
export default Map;
``
1 Answers

You should create another state named error :

const [err, setErr] = useState(null)

useEffect(() => {
  (async () => {

    try {

      let {
        status
      } = await Location.requestForegroundPermissionsAsync();
      if (status !== 'granted') {
        return;
      }

      let location = await Location.getCurrentPositionAsync({}); {
        setUserLocation(location) !== null ?
          isLoading(false) : {}
      }
      setRegion({
        latitude: location ? .coords ? .latitude,
        longitude: location ? .coords ? .longitude,
        latitudeDelta: 0.01,
        longitudeDelta: 0.01,
      })
    } catch (err) {
    isLoading(false)
    setErr("Error in location")
    }
  })();
}, []);

And now you should show some error to user

hope it helps ,feel free for doubts

Related