skip to Main Content

I have a map that is drawing markers for vehicles based on their GPS location inside a .json file. I’m running into problems getting the map to automatically reload the data from the .json file and then redraw the markers based on the new data/location. Here is some excerpts of my code:

const fetchAPI = async () => {
  const url = './cradlepoint.json';
  const response = await fetch(url);
  const locations = await response.json();
  return locations;
};

let data = await fetchAPI();
setInterval(fetchAPI,5000);

This is the fetch call that gets the location from the .json file and that’s working fine; I confirmed that if the .json file changes, it brings in those changes. I added a setInterval to fire that every 5 seconds to grab new location data. Next I build the map and import that data:

async function initMap() {
    const { Map, InfoWindow, KmlLayer } = await google.maps.importLibrary("maps");
    const { Marker } = await google.maps.importLibrary("marker");
    map = new Map(document.getElementById("map"), {
      mapId: "####",
      center: { lat: ###, lng: ### },
      zoom: 14,
    });

  const busicon = "https://maps.google.com/mapfiles/ms/icons/bus.png";
  
  const infoWindow = new InfoWindow();

  function setMarker() {
  var results = data.data.length
  for (let i = 0; i < results; i++){
    var busid = data.data[i].id;
    var buslat = data.data[i].latitude;
    var buslong = data.data[i].longitude;
    const marker = new Marker({
      map: map,
      position: { lat: buslat, lng: buslong },
      icon: busicon,
      title: busid
    });
    // Add a click listener for each marker, and set up the info window.
    marker.addListener("click", ({ domEvent, latLng }) => {
    const { target } = domEvent;

    infoWindow.close();
    infoWindow.setContent(marker.title);
    infoWindow.open(marker.map, marker);
    });
  };
  };

  setMarker()
  setInterval(setMarker,5000)

initMap();

I wrapped my create marker code into a function and then used setInterval to fire that every 5 seconds.

Both the fetch and the setmarker code is automatically running as expected, the problem is I can’t get the updated location info coming out of the fetch call to dump into the "data" declaration. I also suspect I need to add code to delete all markers and then re-draw them; but without getting the updated location data from the fetch, that’s a moot point.

2

Answers


  1. Why not let data = await fetchAPI(); ? I suspect your problem is to construct all those functions into one process that occurs every 5 seconds? Maybe something like this pseudo-code:

    // globals
    let map = null;
    let previous_markers = null
    
    // just for debug
    function delay(millisec) {
      return new Promise(resolve => {
        setTimeout(() => {
          resolve()
        }, millisec);
      })
    }
    
    // fetching the json
    async function fetch_data() {
      console.log("TODO: fetch data");
      await delay(1000);
      return new Array(3).fill(Math.round(Math.random()*10));
    
    }
    
    // setting markers
    async function setMarkers(map, markers) {
      console.log("TODO: set markers on map: " + markers);
    }
    
    // removing markers
    async function removeMarkers(map, markers) {
      console.log("TODO: remove markers from map: " + previous_markers);
    }
    
    
    // google map
    function Map() {
      return "map";
    }
    
    // init map, draw map, remove markers, draw markers 
    async function draw_map(markers) {
      if (map == null) {
        console.log("TODO: init map")
        map = new Map();
      }
      
      if (previous_markers) {
        removeMarkers(map, previous_markers);
      }
      
      setMarkers(map, markers)
    
      previous_markers = markers;
    }
    
    // the process function every 5 seconds
    async function fetch_and_draw() {
      let markers = await fetch_data();
      draw_map(markers);
    }
    
    // main:
    fetch_and_draw();
    setInterval(fetch_and_draw, 5000);
    Login or Signup to reply.
  2. It seems that you are not updating the "data" variable with the new locations when calling to the fetchAPI ().
    You are calling fetchAPI every 5 seconds but not assigning new values to "data".
    Then you can change to :

    let data;
    
    const fetchAPI = async () => {
        //...
        //...
        //...
        //...
        const locations = await response.json();
        data = locations;
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search