Home > Net >  React Native: rendering a list of markers on a map
React Native: rendering a list of markers on a map

Time:12-05

i need your help! I am new to react native and i have this problem: I want to display a list of markers on map where the information are stored in a database (SQLite). I am using react-native-maps, so in the MapView component I have

      return (
    <View style={styles.sectionContainer} >
        <TouchableOpacity  onPress={()=>{console.log(arrayData)}} >
          <Text>elements of arrayData</Text>
        </TouchableOpacity>
      <MapView
        style={styles.map}
        mapType='hybrid'
        initialRegion={{
          latitude: 41.73909537455833,
          longitude: 12.701842524111271,
          latitudeDelta: 0.0922,
          longitudeDelta: 0.0421,}}
      >
  
        { arrayData.map((item, index) => (
          <Marker key={index} title={item.name} coordinate={item.coordinates} />
           ))}
      </MapView>
    </View>
  );

where arrayData is an array of object, every object contain this information: name and coordinate. I tryed to create this array in this way: I define an initial array, a function read elements from the database and it add's in the array and finally return the arrayData(=array). This is my code:

const array = [
    {name: 'a', coordinates: {latitude: 41.73909537455833, longitude: 12.701842524111271,}}
  ]; 

  const location=[
    {latitude: 41.73767484979501, longitude: 12.703637927770613},
    {latitude: 41.738562243639635, longitude: 12.701931037008762},
    {latitude: 41.73870384524446, longitude: 12.700487338006495},
  ];

   const funzione = ()=>{ // get data from database called Users
    try {
      db.transaction((tx) => {
          tx.executeSql(
              "SELECT Title FROM Users", 
              [],
              (tx, results) => {
                  var len = results.rows.length; 
                  if (len > 0) {
                    for(let i=0;i<len;i  ){
                      var userTitle = results.rows.item(i).Title;
                      
                      //add the element in the array
                      array.push({name: userTitle, coordinates: location[i]});
                    }
                  }
              }
          )
      });
       return(array);
     } catch (error) {
     console.log(error)
    }  
  } 
  const arrayData = funzione();

Now the problem is that in the MapView component, the arrayData is only the initial array, then i see only 1 marker. It's as if the function doesn't work correctly, but if I run console.log(arrayData); the output is correct and arrayData has the elements read in the database. Someone can help me? Very thanks!

CodePudding user response:

Probably the problem is because you are rendering the map and the request to get your data from the database is asynchronous, so in the life cycle of the component, the request didn't finish when the Map was rendered. Try to add an useEffect hook to change your information. I adding some changes that you will need do:

1 - Change your function to async and force it to wait the information... something like this:

 db.transaction((tx) => {
     **await** tx.executeSql(
          "SELECT Title FROM Users", 
          [],
          (tx, results) => { ...

2 - Create your array with useState hook instead of a const. Something like:

const [array, setArray] = useState([]); 

3 - Use the hook useEffect to update the markers list information. Like this:

const getData = async () => {
    const response = await funzione();
    setArray(response);
}

useEffect(() => {
    getData ();
}, [])

Any problem just ping me. Have a good day.

CodePudding user response:

The first answer is correct, just piggybacking to say that you will also have to change the body of your sql callback to return a new list of objects:

(tx, results) => {
  return (results?.rows || []).map((row, i) => ({name: row.item.Title, coordinates: location[i]}));
  }

And then append them into your state

setArray([...array, ...response]);
  • Related