cristian9804
cristian9804

Reputation: 93

Dynamically Rendering MapView Marker React Native

This is how my Map View Looks like :

<MapView
                style={styles.mapStyle}
                initialRegion={{
                latitude: 51.524300,
                longitude: -0.037790,
                latitudeDelta: 0.0122,
                longitudeDelta: 0.0421,


            }}
            >
            <Marker
                coordinate={{
                    latitude:51.524464,
                    longitude:-0.036285,
                    latitudeDelta:0.0,
                    longitudeDelta:0.0
                }}
                title={"Marker 1"}
                description={customData.text1} 
            />
            <Marker
                coordinate={{
                    latitude:51.524310,
                    longitude:-0.037798,
                    latitudeDelta:0.0,
                    longitudeDelta:0.0
                }}
                title={"Marker 2"}
                description={customData.text2}
            />
            <Marker
                coordinate={{
                    latitude:51.523174,
                    longitude:-0.039332,
                    latitudeDelta:0.0,
                    longitudeDelta:0.0
                }}
                title={"Marker 3"}
                description={customData.text3}
            />

            </MapView>

As you can see I have hard-coded 3 markers just to make sure that the MapViews works properly. Now, I use an external API which tells the parking spaces based on the user's input. So for example if the user enter's a certain postcode/ ZIP code, the api returns an array where I have various information about the parking space such as longitude and latitude. I want to represent these parking spaces with markers on the map. I use a FlatList for that:

<FlatList
                data = {parkingSpaces}
                renderItem={({ item }) => {
                    return <MapView.Marker
                    coordinate={{
                    latitude: parseInt(item.latitude),
                    longitude:parseInt(item.longitude)
                    }}

                    title = {"parking markers"}

                    />  

                }}
                keyExtractor={item => item.unique_identifier}

            />

I don't get any errors, however I can't see the markers on the map. Below is my full code

import React ,{Component,useState,useEffect} from 'react'
import {View,Text,StyleSheet,Dimensions,Button,Alert,FlatList} from 'react-native'
import MapView , {Marker}from 'react-native-maps'
import axios from 'axios'
import { TextInput } from 'react-native-gesture-handler'
import camdenParking from '../api/camdenParking'
import SearchBar from '../components/SearchBar'



/// Key Secret : 5ulg30lagu2o493uwsmn24rxklsg0ivb05k2zl6xqhiz8js9e7
/// App Secret Token : NTEX14nQLbrS8MIz4RmC6riUV6K2aQ_j687H


const HomeScreen = ()=>

{

    const [parkingSpaces,setparkingSpaces] = useState([])
    const[term,setTerm] = useState('')
    let userLatitude = 0
    let userLongitude = 0 

    const customData = require("./MarkersText.json")


      const searchApi = async() => {

        const response = await camdenParking.get("",{

            params:{
                //longitude:-0.115444,
                //latitude:51.517597
                postcode: term


            }

        }) // you can change this later on
        console.log(response.data)
        setparkingSpaces(response.data)
        console.log(term)      
      }


      const findCoordinates = () => {
        navigator.geolocation.getCurrentPosition(
          position => {
            const locationString = JSON.stringify(position); // Here we get the JSON object but it needs to be parsed
            var longLat = JSON.parse(locationString); // Here we parse the JSON object

             userLatitude=longLat.coords.latitude
             userLongitude=longLat.coords.longitude

             console.log(userLatitude) // This prints the current latitude from the user
             console.log(userLongitude) // This prints the longitude



          },
          error => Alert.alert(error.message),
          { enableHighAccuracy: false, timeout: 20000, maximumAge: 1000 }
        );
      };


     //useEffect(()=>{
       // searchApi()
     //},[])



    return(


        <View style={styles.container}>
            <SearchBar 
                term={term}
                onTermChange={newTerm=>setTerm(newTerm)}
                onTermSubmit={()=> searchApi(term)}
                />
            <MapView
                style={styles.mapStyle}
                initialRegion={{
                latitude: 51.524300,
                longitude: -0.037790,
                latitudeDelta: 0.0122,
                longitudeDelta: 0.0421,


            }}
            >
            <Marker
                coordinate={{
                    latitude:51.524464,
                    longitude:-0.036285,
                    latitudeDelta:0.0,
                    longitudeDelta:0.0
                }}
                title={"Marker 1"}
                description={customData.text1} 
            />
            <Marker
                coordinate={{
                    latitude:51.524310,
                    longitude:-0.037798,
                    latitudeDelta:0.0,
                    longitudeDelta:0.0
                }}
                title={"Marker 2"}
                description={customData.text2}
            />
            <Marker
                coordinate={{
                    latitude:51.523174,
                    longitude:-0.039332,
                    latitudeDelta:0.0,
                    longitudeDelta:0.0
                }}
                title={"Marker 3"}
                description={customData.text3}
            />

            </MapView>
            <Text>We have found {parkingSpaces.length} results</Text>
            <Button onPress={searchApi} title=" Click Here To Get Parking Spaces" />
            <Button onPress={findCoordinates} title=" Click Here To Get User's Location" />
            <Text>Parking Spaces found around {term}</Text>

            <FlatList
                data = {parkingSpaces}
                renderItem={({ item }) => {
                    return <MapView.Marker
                    coordinate={{
                    latitude: parseInt(item.latitude),
                    longitude:parseInt(item.longitude)
                    }}

                    title = {"parking markers"}

                    />  

                }}
                keyExtractor={item => item.unique_identifier}

            />

            <FlatList 
                data = {parkingSpaces}
                renderItem={({ item }) => {
                    return <Text> {item.road_name} | Possible Available Spaces:{item.parking_spaces} </Text>

                }}
            keyExtractor={item => item.unique_identifier}

            />


        </View>
    );
};

const styles = StyleSheet.create(
    {
     container:{
         flex:1,
         backgroundColor: '#fff',
         //alignItems: 'center',
         //justifyContent: 'center',
         //...StyleSheet.absoluteFillObject,
         //marginLeft:0,
         //height:400,
         //width:400,
         //justifyContent:"flex-end",
         //alignItems:"center",   
     },

     mapStyle: {
        width: 400,
        height:400, 
        //width: Dimensions.get('window').width,
        //height: Dimensions.get('window').height,
      },
    }

)

export default HomeScreen

UPDATE

This is how my code looks like now:

import React ,{Component,useState,useEffect} from 'react'
import {View,Text,StyleSheet,Dimensions,Button,Alert,FlatList} from 'react-native'
import MapView , {Marker}from 'react-native-maps'
import axios from 'axios'
import { TextInput } from 'react-native-gesture-handler'
import camdenParking from '../api/camdenParking'
import SearchBar from '../components/SearchBar'



/// Key Secret : 5ulg30lagu2o493uwsmn24rxklsg0ivb05k2zl6xqhiz8js9e7
/// App Secret Token : NTEX14nQLbrS8MIz4RmC6riUV6K2aQ_j687H


const HomeScreen = ()=>

{

    const [parkingSpaces,setparkingSpaces] = useState([])
    const[term,setTerm] = useState('')
    let userLatitude = 0
    let userLongitude = 0 

    const customData = require("./MarkersText.json")


      const searchApi = async() => {

        const response = await camdenParking.get("",{

            params:{
                //longitude:-0.115444,
                //latitude:51.517597
                postcode: term


            }

        }) // you can change this later on
        console.log(response.data)
        setparkingSpaces(response.data)
        console.log(term)      
      }


      const findCoordinates = () => {
        navigator.geolocation.getCurrentPosition(
          position => {
            const locationString = JSON.stringify(position); // Here we get the JSON object but it needs to be parsed
            var longLat = JSON.parse(locationString); // Here we parse the JSON object

             userLatitude=longLat.coords.latitude
             userLongitude=longLat.coords.longitude

             console.log(userLatitude) // This prints the current latitude from the user
             console.log(userLongitude) // This prints the longitude



          },
          error => Alert.alert(error.message),
          { enableHighAccuracy: false, timeout: 20000, maximumAge: 1000 }
        );
      };


     //useEffect(()=>{
       // searchApi()
     //},[])



    return(


        <View style={styles.container}>
            <SearchBar 
                term={term}
                onTermChange={newTerm=>setTerm(newTerm)}
                onTermSubmit={()=> searchApi(term)}
                />
            <MapView
                style={styles.mapStyle}
                initialRegion={{
                latitude: 51.524300,
                longitude: -0.037790,
                latitudeDelta: 0.0122,
                longitudeDelta: 0.0421,
                }}
                >
                {parkingSpaces.map((val, index) => {
                return (<MapView.Marker
                        coordinate={{
                        latitude: parseInt(val.latitude),
                        longitude:parseInt(val.longitude)
                        }}
                        key={index}
                        title = {"parking markers"}
                        />); 

                })}

            </MapView>

            <Text>We have found {parkingSpaces.length} results</Text>
            <Button onPress={searchApi} title=" Click Here To Get Parking Spaces" />
            <Button onPress={findCoordinates} title=" Click Here To Get User's Location" />
            <Text> WC2A 3PD</Text>
            <Text>Parking Spaces found around {term}</Text>

            <FlatList
                data = {parkingSpaces}
                renderItem={({ item }) => {
                    return <MapView.Marker
                    coordinate={{
                    latitude: parseInt(item.latitude),
                    longitude:parseInt(item.longitude),
                    latitudeDelta:0.0,
                    longitudeDelta:0.0
                    }}

                    title = {"parking markers"}
                    description = {"parking"}


                    />  

                }}
                keyExtractor={item => item.unique_identifier}


            />

            <FlatList 
                data = {parkingSpaces}
                renderItem={({ item }) => {
                    return <Text> {item.road_name} | Possible Available Spaces:{item.parking_spaces} </Text>

                }}
            keyExtractor={item => item.unique_identifier}

            />


        </View>
    );
};

const styles = StyleSheet.create(
    {
     container:{
         flex:1,
         backgroundColor: '#fff',
         //alignItems: 'center',
         //justifyContent: 'center',
         //...StyleSheet.absoluteFillObject,
         //marginLeft:0,
         //height:400,
         //width:400,
         //justifyContent:"flex-end",
         //alignItems:"center",   
     },

     mapStyle: {
        width: 400,
        height:400, 
        //width: Dimensions.get('window').width,
        //height: Dimensions.get('window').height,
      },
    }

)

export default HomeScreen

Upvotes: 3

Views: 3741

Answers (1)

Tim
Tim

Reputation: 10709

The first problem is the use of FlatList as container for your markers. The solution is to map over your parkingSpaces array in between your MapView. The second problem is that you call parseInt on your coordinates, which causes the map to not render your markers at all. In addition you would lose precision.

Code:

<MapView
 style={styles.mapStyle}
 initialRegion={{
 latitude: 51.524300,
 longitude: -0.037790,
 latitudeDelta: 0.0122,
 longitudeDelta: 0.0421,
}}
 >
 {parkingSpaces.map((val, index) => {
  return (<MapView.Marker
          coordinate={{
          latitude: val.latitude,
          longitude: val.longitude
          }}
          key={index}
          title = {"parking markers"}
         />); 
 })}

</MapView>

Working Demo:

https://snack.expo.io/@tim1717/mature-croissant

Upvotes: 4

Related Questions