Search code examples
javascriptreact-nativehere-apireact-native-maps

Here map integration using React native


I've been trying to integrate Here Maps on my react native app, I followed this "tutorial" but with no success. I think the tutorial is for Expo only.

Here map integration in react-native mobile app

And here is the code I wrote

import React from 'react';
import {
    SafeAreaView,
    ScrollView,
    StatusBar,
    StyleSheet,
    Text,
    useColorScheme,
    View,
    TextInput
  } from 'react-native';

import MapView,{Polyline, Marker}from 'react-native-maps';
import axios from 'axios'


class ShowMap extends React.Component{

    constructor(props){
        super(props)
        this.state = {
            startingLocation: {
                latitude: "37.025",
                longitude: "-122.023",
            },
            finishLocation: {
               latitude: "37.78825",
               longitude: "-122.4324",
            },
            region: {
                latitude: parseFloat("37.025"),
                longitude: parseFloat("-122.023"),
                latitudeDelta: 0.0922,
                longitudeDelta: 0.0421,
              },
              isLoading: true
        }
    }
            
    _getRoute = () => {
        let from_lat = parseFloat(this.state.startingLocation.latitude)
        let from_long = parseFloat(this.state.startingLocation.longitude)
        let to_lat = parseFloat(this.state.finishLocation.latitude)
        let to_long = parseFloat(this.state.finishLocation.longitude)
        let route_coordinates = []
        axios.get(`https://route.ls.hereapi.com/routing/7.2/calculateroute.json?apiKey={api_key_here}&waypoint0=geo!${from_lat},${from_long}&waypoint1=geo!${to_lat},${to_long}&mode=fastest;car;traffic:disabled`).then(res => {
            // here we are getting all route coordinates from API response
            res.data.response.route[0].leg[0].shape.map(m => {
                // here we are getting latitude and longitude in seperate variables because HERE sends it together, but we
                // need it seperate for <Polyline/>
                let latlong = m.split(',');
                let latitude = parseFloat(latlong[0]);
                console.log(latitude);
                
                let longitude = parseFloat(latlong[1]);
                console.log(longitude);

                routeCoordinates.push({latitude: latitude, longitude: longitude});
            })
            this.setState({
                routeForMap: routeCoordinates,
                // here we can access route summary which will show us how long does it take to pass the route, distance etc.
                summary: res.data.response.route[0].summary,
                // NOTE just add this 'isLoading' field now, I'll explain it later
                isLoading: false,
            })

        }).catch(err => {
            console.log(err)
        })
    }

    componentDidMount() {
        // when this function is finished, we will set isLoading state to false to let program know that API request has finished and now we can render the map
        this._getRoute()
      }
    
    render() {
        if(this.state.isLoading) {
            return (
              <Text>Loading...(you could also use or what ever you want to show while loading the request)</Text>
            )
          } else{
        return (
<MapView region={this.state.region}>
  <Polyline coordinates={this.state.routeForMap} strokeWidth={7} strokeColor="red" geodesic={true}/>
  <Marker coordinate={{latitude: parseFloat(this.state.startingLocation.latitude), longitude: parseFloat(this.state.startingLocation.longitude)}} title="Starting location"/>
  <Marker coordinate={{latitude: parseFloat(this.state.finishLocation.latitude), longitude: parseFloat(this.state.finishLocation.longitude)}} title="Finishlocation"/>
</MapView>
        );
      }
    }


}

const styles = StyleSheet.create({
    container: {
      ...StyleSheet.absoluteFillObject,
      height: 400,
      width: 400,
      justifyContent: 'flex-end',
      alignItems: 'center',
    },
    map: {
      ...StyleSheet.absoluteFillObject,
    },
   });

   export default ShowMap;

and here is the result I get Output


Solution

  • You are missing &legAttributes=shape at the end of your Axios request URL.

    I assume that res.data.response.route[0].leg[0].shape gives an error since there is no shape array since you didn't set that in the request URL and then it goes to catch that error in Axios. Which in the end never sets isLoading to false.

    In the end, your Axios get should look like this:

    axios.get(`https://route.ls.hereapi.com/routing/7.2/calculateroute.json?apiKey={api_key_here}&waypoint0=geo!${from_lat},${from_long}&waypoint1=geo!${to_lat},${to_long}&mode=fastest;car;traffic:disabled&legAttributes=shape`).then(res => {
    

    Let me know if it still doesn't work.