Beginning the process of setting up information windows for map markers with the help

As I work on dynamically adding info windows to Google Maps markers from a JSON array received from the server, I find myself grappling with Javascript's handling of variables and scope.

One attempt involved this code snippet:

$.getJSON("server", function(data) {
        if (data.items.length > 0 {
            var infowindow = new google.maps.InfoWindow({
              content: "placeholder"
            });
            for (var i = 0; i < data.items.length; i++) {
              var latLng = new google.maps.LatLng(data.items[i]["lat"],
                                                  data.items[i]["lng"]);
              var marker = new google.maps.Marker({
                position: latLng,
                map: map,
                title: data.items[i]["text"],
                icon: data.items[i]["alert_type"],
                animation: google.maps.Animation.DROP
              });
              marker.addListener('click', function() {
                infowindow.setContent(data.items[i]["text"]);
                infowindow.open(map, this);
              });
            } // end for
        } // end if
    }); // end getJSON

This code runs into an issue where clicking a marker triggers an error stating data.items[i] is undefined. Despite being defined earlier in the code, multiple attempts to access it within the function have failed.

To circumvent the problem, I initialized a variable just before the function declaration:

var reportText = data.items[i]["text"];
. Subsequently, altering the problematic line to
infowindow.setContent(reportText);
resolved the errors. However, all markers displayed the same text upon click, reflecting the last retrieved report instead of individualized information. Presumably, the infowindow retained the variable location rather than the string value when set, resulting in this behavior.

In another iteration, I modified my approach to initialize the marker differently:

var marker = new google.maps.Marker({
  position: latLng,
  map: map,
  title: data.items[i]["text"],
  icon: data.items[i]["alert_type"],
  label: reportText,
  animation: google.maps.Animation.DROP
});

By assigning the label property accordingly, I could utilize:

infowindow.setContent(this.label);

This adjustment successfully displayed the correct text for each marker in the info window. However, the method proved incompatible with custom icons meant to accommodate labels, which resulted in less aesthetic marker appearances.

My goal now is to either conceal the label property while retaining its functionality, or ideally, modify setContent to capture the string value at the time of execution instead of creating a reference point to a variable.

Any guidance on this matter would be greatly appreciated. Thank you.

Answer №1

Upon reviewing the question posed in the initial comment by @geocodezip and experimenting with my own code, I was able to develop a functional solution. While I am not entirely satisfied with the use of a global array, it does produce the desired outcome. Below is the updated version of the code:

var texts = [];

function makeRequest() {
    $.getJSON("server/reports", function(data) {
        if (data.items.length > 0) {
            var infowindow = new google.maps.InfoWindow({
              content: "placeholder"
            });
            var text = "<ul>";
            for (var i = 0; i < data.items.length; i++) {
              var reportText = data.items[i]["text"];
              texts.push(reportText);
              text += "<li>"; 
              text += data.items[i]["text"] + "<br />";
              text += data.items[i]["end_date"];
              text += "</li>";
              var latLng = new google.maps.LatLng(data.items[i]["lat"],
                                                  data.items[i]["lng"]);
              var marker = new google.maps.Marker({
                position: latLng,
                map: map,
                title: data.items[i]["text"],
                icon: data.items[i]["alert_type"],
                animation: google.maps.Animation.DROP
              });
              google.maps.event.addListener(marker, 'click', (function(marker, i) {
                return function() {
                  infowindow.setContent(texts[i]);
                  infowindow.open(map, marker);
                }
              })(marker, i));
            } // end for
            text += "</ul>"
        } // end if
        document.getElementById("content").innerHTML = text;
    }); // end getJSON
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Validation of drop-down lists

How can I validate whether a TextBox is empty when a Dropdown list's selected index changes in ASP.NET using validation controls? ...

Ajax response values overlap

I am developing an application that requires multiple Ajax requests, but I encountered a problem where I am receiving the same response values for both requests. Each request must include a data field called activityCode, yet I keep getting the value of Sc ...

Remove an image that has been selected while uploading multiple images using AngularJS

If I want to delete a specific image from multiple uploads by clicking on the image in AngularJS, how can I achieve this? Each uploaded image has an associated textbox. When the delete icon on the image is clicked, both the image and the corresponding text ...

Using Nunjucks to create and populate arrays within templates

Currently, I am facing an issue with initializing an AmCharts data within a Nunjucks template. I have retrieved the data from req.body and passed it as chartData. // In server.js var html = nunjucks.render("template.html", { chartData: req.body // cha ...

Guide on subscribing to an object from a service in Angular 2/5

I am facing an issue where I need to update my property component with data received from the server. In the Service, I have implemented something like this: private events: Event[] = []; eventChanged = new Subject<any>(); // Edit: added an observa ...

Leveraging NestJs Libraries within Your Nx Monorepo Main Application

I am currently part of a collaborative Nx monorepo workspace. The setup of the workspace looks something like this: https://i.stack.imgur.com/zenPw.png Within the structure, the api functions as a NestJS application while the data-access-scripts-execute ...

What are the steps to align my PSQL database with my Prisma migration without having to reset the entire database?

After creating a schema model named Appointment with various fields and roles, I decided to make changes by adding the "status" field directly to the Appointment table using the psql query tool. Subsequently, I updated the schema model to include the new ...

Encoding a JSON representation of an HTML list where all children are displayed at each parent item

Here is the structured list that I am currently working with: function convert( name_ref ) { name_ref = name_ref + " > ol > li"; var mylist = []; $(name_ref).each(function () { if ($(this).find('> ol > li').length){ myl ...

Is it possible to display the <input type="text"> and the following <div> element on the same line instead of having space between them?

Could you please advise on how to adjust the layout to eliminate the space between the input type="text" and the following div element? When I set the width of the input type="text element to 180px and the width of the subsequent div to 20px, the div overf ...

React component rendering twice due to width awareness

In a React component that I've developed, I have utilized ResizeObserver to track its own width. Within this component, two divs are rendered with each having a "flex: 1" property to ensure equal width distribution. Under certain conditions, such as w ...

Troubleshooting: Why is my switch-case statement in TypeScript not functioning as expected

Here is a simple switch case scenario: let ca: string = "2"; switch (ca) { case "2": console.log("2"); case "1": console.log("1"); default: console.log("default"); } I am puzzled by the output of this code, which is as follows: 2 1 defa ...

Tips for retrieving a cropped image with Croppr.js

Currently, I am developing a mobile application using Ionic 3. Within the application, I have integrated the Croppr.js library to enable image cropping before uploading it to the server. However, I am facing an issue where I am unable to retrieve the cropp ...

How to modify the background color in Material Ui's datepicker?

Is there a way to customize the background color of my Material UI datepicker modal? To change the colors, you can use the createMuiTheme function from "@material-ui/core": const materialTheme = createMuiTheme({ overrides: { MuiPickersToolbar: ...

Toggle class for a div upon clicking

I am attempting to add a class to a div element when it is clicked. Unfortunately, I'm having trouble getting it to work despite setting it up in the following manner: Javascript: function choose() { this.addClass("selected"); } HTML: <div ...

extracting values from deeply nested JSON array in JavaScript

Is there a way to extract values from a deeply nested JSON array? I'm looking to retrieve all pairs of (nameValue and value) from the JSON provided below var json = [{ name: 'Firstgroup', elements: [{ ...

What is the best way to display the time of a post update similar to the style of

I am currently working on creating a notification deck. Instead of displaying the time when a notification was received, I aim to show the time that has passed since its arrival similar to how Twitter and Facebook do it with formats like "32m" or "1 hour a ...

jQuery TextExt - Trouble with setting the URL for Ajax autocomplete

Currently, I am utilizing the jQuery TextExt plugin for autocomplete. While using its example json url (data.json), everything functions as expected without any issues. However, when attempting to use my own custom url, similar to the one below: $('# ...

Filter Dropdown List Based on Another Dropdown List in JavaScript

Seeking expert guidance here! Currently working with Electron and have three key files that are involved in pulling data from a SQLite database (Data.js), organizing this data into arrays, and making it accessible through dropdown lists (Model.js and View. ...

Go through the array and perform an action once you reach the final occurrence

I have a challenge where I need to iterate over an array that contains data fetched from a .txt file on a server. The content of the file appears as follows: 12345|Test message 55555|55555's message 12345|Test message 2 After making a simple GET req ...

Leveraging ng-transclude and the require attribute for effective communication between directives

I'm working with two directives, let's call them: angular.module('app').directive('directiveX', directiveX); function directiveX(){ return { restrict: 'E', transclude: true, ...