What's the best way to retrieve information from Mongodb in order to generate a map marker?

I have a map where I need to place markers. I've created a collection in MongoDB and have a sample data set ready for the marker. However, I am having trouble retrieving the data and actually creating the marker on the map.

The Map

Meteor.startup(function() {  
        GoogleMaps.load();
      });

      Template.map.helpers({  
        mapOptions: function() {
          if (GoogleMaps.loaded()) {
            return {
              center: new google.maps.LatLng(-37.8136, 144.9631),
              zoom: 8
            };
          }
        }
      });

      Template.map.helpers({
        marker: function() {
          return MarkerData.find();
         }
      });
      

Creating Markers

for (var i = 0; i < MarkerData.length; i++) {
        var lat = {{ lat }}
        var lng = {{ lng }}
        var title = {{ title }}
        var address = {{ address }}
        var url = {{ url }}
        var marker = new google.maps.Marker({
          position: new google.maps.LatLng(lat, lng),
          map: map,
          title: title,
          animation: google.maps.Animation.DROP,
        });
      }
      

My Collection

MarkerData = new Mongo.Collection('markerdata');    
      

Data within the Collection

if (MarkerData.find().count() === 0) {
        MarkerData.insert({
          lat: 34.200659,
          lng: -118.519986,
          title: 'Extensions Plus HQ',
          address: '17738 Sherman Way Reseda, CA 91335',
          url: 'http://extensionsplus.com'
        }); 
      } 
      

I will continue adding more data into the collection. This is just a test to ensure the code works properly.

Answer №1

Fortunately, I recently included a similar feature in an application. Working with Meteor has shown me that adding a collection of markers to a Google map can be tricky, especially with around 20 markers. To address this issue, I have implemented a 500ms delay between each rendering, which adds complexity to the code. Below is the updated and functional code based on your requirements:

Template.map.onCreated(function () {
  var self = this;

  // Initialize the map
  self.state = new ReactiveDict('myTemplate.state');
  self.state.set('mapMarkers', []);

  // Set up the map
  GoogleMaps.ready('myMap', function (map) {
    self.state.set('mapReady', true);
  });
});

Template.map.onRendered(function(){
  var self = this;
  // Add markers to the UI when ready
  // Note: Google Maps may not handle adding all markers at once properly, leading to errors.
  // We push markers to an array first and then render them separately with a delay using autorun.
  GoogleMaps.ready('myMap', function onMapReady(map) {
    // Setting up dependencies
    var isMapReady = self.state.get('mapReady');
    var hasData = !!MarkerData.findOne();
    var isGoogleDefined = typeof(google) !== 'undefined';
    var theMarkers = MarkerData.find({}, {sort: {state:1}});
    var allMarkers = [];
    var infoWindows = [];

    if ( isMapReady && hasData && isGoogleDefined ) {
      var markers = theMarkers.fetch();

      _.each(markers, function (marker, i, cursor) {
        var latitude = marker.lat;
        var longitude = marker.lng;
        var latlng = new google.maps.LatLng(latitude, longitude);

        // Building the info window for marker details
        infoContent = '<strong>' + marker.title + '</strong>' +'<br/>' + marker.address;
        
        infoWindow = new google.maps.InfoWindow({
          content: infoContent,
          disableAutoPan: true
        });

        // Creating the marker to place on the map
        marker = new google.maps.Marker({
          position: latlng
        });

        // Adding the marker to the UI state
        allMarkers.push(marker);
        infoWindows.push(infoWindow);
        self.state.set('mapMarkers', markers);
      });
    }

    self.autorun(function () {
      var markerLength = allMarkers.length;
      var targetLength = theMarkers.count();

      if ( markerLength === targetLength ) {
        _.each(allMarkers, function( marker, index, list ){
          Meteor.setTimeout(function(){
            var mapInstance = GoogleMaps.maps.myMap.instance;

            // Placing the marker on the map
            marker.setMap(mapInstance);
            
            google.maps.event.addListener(marker, 'click', function () {
              infoWindows[index].open(mapInstance, marker);
            });
            
            google.maps.event.addListener(marker, 'mouseout', function () {
              infoWindows[index].close();
            });
          }, 500);
        });
      }
    });
  });
});

Template.map.helpers({
  mapOptions: function () {
    if (GoogleMaps.loaded()) {
      return {
        center: new google.maps.LatLng(-37.8136, 144.9631),
        zoom: 8
      };
    } else {
      return null;
    }
  },
  allMarkers: function () {
    return MarkerData.find();
  }
});

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

Filtering records by a joined association in Rails using Ajax

My goal is to enable an end user to filter a data grid based on an associated record. The data grid currently displays a list of Activities: The model for activity.rb (the list of records) class Activity < ApplicationRecord belongs_to :student ...

Unresolved styles in React component linked to styles.css file

As I dive into creating a registration page in ReactJS, I encounter a frustrating issue with my styles not applying correctly from the styles.css file. Let's take a look at my RegisterPage.jsx component: export default function RegisterPage() { ret ...

The Facebook messenger checkbox plugin does not appear to be displaying correctly

I have integrated the Facebook Messenger Checkbox Plugin into my AngularJS application by following the guide provided at this link. Initially, I was able to successfully display the messenger checkbox plugin on a page. However, upon navigating to another ...

Revamp the layout of the lower HTML video menu

Here is my code: <html> <head> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <style> video { width: 100%; height: auto; } </style> </head> <body> <video width="400" controls> ...

Struggles with integrating a disappearing navigation bar when scrolling - JavaScript

I've been struggling with a fixed position navbar on my blog and I'm attempting to incorporate basic JS to hide the navbar while scrolling down and have it reappear when scrolling up. You can find the code snippet I'm trying to implement in ...

Once this code is executed, Javascript ceases to function

I have developed a code snippet to create a typing effect similar to a command console. While the code is functioning well on its own, any additional code I add after it seems to malfunction. I've spent quite some time troubleshooting this issue witho ...

passport.js and express.js working together to seamlessly redirect users back to the original page after completing oauth authentication

How can I navigate users to the same page after an OAuth request to Twitter by setting a session variable? Here is how the routes are currently configured: // Authentication routes (function () { app.get('/auth/twitter', passport.authentica ...

Unable to locate the index.js entry file in React Native

I have a simple React Native application. I am attempting to test it on a virtual Android device by navigating to the project and running npm start -- --reset-cache. After terminating the process, I enter the command react-native run-android. Despite havin ...

Zone.js error: Promise rejection caught

When I call a function from an external library on page load in my Angular application, Chrome dev tools console shows the error message: "Unhandled Promise rejection: Cannot read properties of undefined (reading 'page') ' Zone: <root> ...

Leveraging NextJS14 Static Site Generation (SSG) for seamless Authentication with Clerk

Having a bit of trouble with Next.js Static Site Generation (SSG) and protected routes. SSG requires data to be available at build time, while protected routes need user authentication which isn't possible during this phase. The pages I'm trying ...

Breaking free from JavaScript[/CSS] within <script>[/<style>] tags: Discovering the flaws in the current system

Being primarily a server-side web developer, my exposure to JavaScript has been limited to externally referenced files and event handlers with minimal initialization functions between <script> tags. Recently, I discovered that the data within <sc ...

Utilizing React Router V4 to Render Dual Components on a Single Route

Looking for help with these routes <Route exact path={`/admin/caters/:id`} component={Cater} /> <Route exact path={'/admin/caters/create'} component={CreateCater} /> After visiting the first route, I see a cater with an ID display ...

Locate an element by filtering and finding two distinct values using the .eq() method

I need help filtering a table row based on the values in two different columns. The idea is to show only the row where one column has "value1" and another column has "value2", while hiding all other rows. If none of the rows meet this condition, then hide ...

Issues with excessive firing of JQuery blur and hide functions

I am currently using jQuery v1.11.2 and have set up a basic JSFiddle at this link (http://jsfiddle.net/k1g3upbv/). The layout may not be ideal in JSFiddle due to the integration of Twitter Bootstrap within my project. I quickly put together the JSFiddle, o ...

Utilizing a function to populate an attribute using .attr() in d3

I utilize .attr to generate link paths in D3, as demonstrated in Lines 42 of the live demo: link.each(function (d){}) .attr('x1', function (d) { return d.source.x; }) .attr('y1', function (d) { return d.source.y; }) .a ...

The directive attribute in AngularJS fails to connect to the directive scope

I have been attempting to pass an argument to a directive through element attributes as shown in the snippet below: directive app.directive('bgFluct', function(){ var _ = {}; _.scope = { data: "@ngData" } _.link = function(scope, el ...

Unable to launch meteor application because of mongo's unexpected exit

I'm attempting to launch the angular2-boilerplate demo on my virtual machine, running Ubuntu 16.04.1 LTS, but encountering an issue preventing the application from starting: [[[[[ ~/Personal/myApp ]]]]] => Started proxy. Unexpected mongo exit cod ...

What steps do I need to take to ensure the progress bar extends all the way to the end of the sn

I am currently facing a challenge where the progress bar line in my message queue does not reach the end of the message before it closes. I have included a brief video showcasing the issue along with the relevant code snippet. Any suggestions or ideas woul ...

Utilize the onChangeText function in React Native to filter out each individual value within a nested array

I currently have an array with nested children in it, where the children can range from one to multiple values. I am working on implementing a local filter within my component. Whenever a user types anything into the textInput, the application will display ...

Troubleshooting logic errors and repetitive functions in AngularJS

My code using AngularJS is experiencing a logic error. I have created a function that iterates through a JSON array and retrieves the weather conditions as strings, such as 'clear', 'cloudy', etc. The function then compares these string ...