Home > Enterprise >  Leaflet : How to create marker labels based on JSON fetched from API
Leaflet : How to create marker labels based on JSON fetched from API

Time:10-26

In my web application, users are shown a map with markers which they can press. When clicking a marker, a detail view appears with an image and text. The image and text are retrieved from a database, and are unique to the marker (each marker has different images and text). I've been able to set down markers, and save information to a database, but when I try to retrieve the specific marker's data from my database when clicking onto a marker, it shows everything retrieved from the database and not the marker specific information.

async function getData() {
    const response = await fetch('/api');
    const data = await response.json();

    for (item of data) {
        // This prints the markers in the co-ordinates stored in the database.
        L.marker([item.lat, item.lon]).addTo(map).on('click', openobjectMenu);

        // This is meant to give the markers their specific text and image.
        const objectMenu= document.querySelector("#objectMenuBody");

        const div = document.createElement("div");
        const title = document.createElement("h2");
        const lineBreak = document.createElement('br');

        const image = document.createElement("img");
        image.setAttribute("src", "images/default.png");
        image.setAttribute("alt", "Default image");

        title.textContent = "No description available.";
        if (item.objDescription) {
            title.textContent = item.objDescription;
        }
        div.appendChild(title);
        div.appendChild(lineBreak);

        objectMenu.appendChild(div);
    }
}

This is the code to print markers and to give the markers their information that is stored in the database. However, instead of, for example, clicking on a marker in Berlin and being shown 'BERLIN TEST' in the object view, it shows:

SHANGHAI TEST

LONDON TEST

BERLIN TEST

USA TEST

MOSCOW TEST

Where did I go wrong? I need the markers to only show their specific descriptions (objDescription) and not every description from the database.

EDIT :

The issue title was updated to better reflect the desired solution.

CodePudding user response:

The response is ok, and your code for iterating on the response JSON object seems ok too.

I don't know what the code for openobjectMenu is, but from what I can see, you are creating the divs and already adding them inside of an element with id objectMenuBody (most likely on your html code). This makes it so that they are visible since the beginning.

I'm guessing you are using Leaflet because of the L.marker on your code.

I think think what you want to do is to add labels to markers, so most likely using the marker.bindPopup("<b>Hello world!</b><br>I am a popup.") is the proper way to go.

You have an example here https://leafletjs.com/examples/quick-start/ .

So instead of this code you wrote :

const div = document.createElement("div");
        const title = document.createElement("h2");
        const lineBreak = document.createElement('br');

        const image = document.createElement("img");
        image.setAttribute("src", "images/default.png");
        image.setAttribute("alt", "Default image");

        title.textContent = "No description available.";
        if (item.objDescription) {
            title.textContent = item.objDescription;
        }
        div.appendChild(title);
        div.appendChild(lineBreak);

You would just directly build a string with the HTML that you should pass to the .bindPopup method.

Quick example:

const pp = `<div><h2>${item.objDescription}</h2><img src="${item.image64}" /></div>`;
const marker = L.marker([item.lat, item.lon]).addTo(map);
marker.bindPopup(pp);
  • Related