skip to Main Content

I’m having an html file location.html and a file with data location.data both on the same webserver in the same directory. the contens of location.data is always the current location data in the form

{"lat":"44.17027","lon":"15.595542","timestamp":"1723663819127","hdop":"2.394","altitude":"510.35","speed":"0.73396146"}

it is written via json_encode() in another php file.
Now I need to read this data in a javascript in location.html into an array to display it on a map via leaflet. (It has to be html)

I just can’t manage to get this done. I tried XMLHttpRequest() with no success. Would appreciate any other (elegant) method.

<script>
var locx = new XMLHttpRequest();

locx.open('GET', 'location.data');

locx.onreadystatechange = function () {
   if (locx.readyState === 4 && locx.status === 200) {
       var locationData = locx.responseText;
   }
};

locx.send();
</script>

2

Answers


  1. If the fetch works (and it should), then the rest will look like this

    Working example using PHP to generate JSON

    https://plungjan.name/SO/leafletjson

    const showMap = data => {
      const { lat, lon } = data;
    
      // Initialize the map
      const map = L.map('map').setView([lat, lon], 13); // 13 is zoom level
    
      // Add OpenStreetMap tile layer
      L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: '&copy; OpenStreetMap contributors'
      }).addTo(map);
    
      // Add a marker to the map at the fetched coordinates
      L.marker([lat, lon]).addTo(map)
        .bindPopup(`Location: [${lat}, ${lon}]`)
        .openPopup();
    };
    
    showMap(data); // remove this line on your server and uncomment the fetch
    /* 
    fetch('location.data') // or fetch('jsonGeneratingPHP.php')
      .then(response => {
        if (!response.ok) { // added more fine grained error handling
          throw new Error(`Network response was not ok (status: ${response.status})`);
        }
        return response.json(); // Parse the JSON only if the response is ok
      })
     .then(showMap)
      .catch(error => console.error('Error fetching the location data:', error));
    */  
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
    <div id="map" style="height: 400px;"></div>
    
    
    
    <script>
    // delete this script on your server and uncomment the commented fetch 
    // test data, remove when fetch works
    const data = { "lat": "44.17027", "lon": "15.595542", "timestamp": "1723663819127", "hdop": "2.394", "altitude": "510.35", "speed": "0.73396146" };
    </script>
    Login or Signup to reply.
  2. You should be using fetch() to get the data via an HTTP GET request from the server and then parse the JSON into a JavaScript object. Then use the information in that object to display a marker on the map (or whatever you want to do) using leaflet.

    Leaflet code part is based on mplungjan’s answer and was added later to give you a full answer including all relevant parts of the question.

    (async() => {
      async function fetchLocation(){
        const mockedApiResponse = `{"lat":"44.17027","lon":"15.595542","timestamp":"1723663819127","hdop":"2.394","altitude":"510.35","speed":"0.73396146"}`
        const response = await fetch("https://httpbin.org/post", {
          method: "POST",
          body: mockedApiResponse,
        })
        if (!response.ok) {
          throw new Error(`Failed to fetch location.data with status code ${response.status}`);
        }
        const locationData = await response.json()
        return locationData.json; // here I need to use .json since the HTTP Bin API returns more data, but this line will be unnecessary for you
      }
      
      function displayOnMap(location){
        const { lat, lon: lng } = location;
        // Initialize the map
        const zoomLevel = 15;
        const map = L.map("myMap")
                     .setView([lat, lng], zoomLevel);
    
        // Add OpenStreetMap tile layer
        L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { attribution: '&copy; OpenStreetMap contributors' }).addTo(map);
    
        // Add a marker for location
        L.marker([lat, lng])
          .addTo(map)
          .bindPopup(`Coordinates: ${lat}, ${lng}`)
          .openPopup();
      }
      
      const location = await fetchLocation();
      displayOnMap(location);
    })();
    <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
    <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
    <div id="myMap" style="height: 200px;"></div>

    In fetchLocation() above there is some stuff I just needed to include to get a working example here on this page (e.g. use POST instead of GET, to allow for the API to return the data I give it etc.). In your case you can leave all that out and just use below code:

    const response = await fetch("location.data");
    if (!response.ok) {
      throw new Error(
        `Failed to fetch location.data with status code ${response.status}`
      );
    }
    return await response.json();
    

    You should also add some error handling using try...catch.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search