Whenever i run the console.log(lat) the value i get returned is undefined - I have the suspicion that it’s because the data from the collection RegisteredStorage hasn’t been fetched yet by the time the code is processed ? however I check for the subscription to be ready in the template before running placeMarkers.
Meteor.startup(function() {
GoogleMaps.load();
});
Template.Map.helpers({
exampleMapOptions: function() {
// Make sure the maps API has loaded
if (GoogleMaps.loaded()) {
// Map initialization options
return {
center: new google.maps.LatLng(-37.8136, 144.9631),
zoom: 8
};
}
},
placeMarkers: function(){
var Users = RegisterStorage.find({"Space":22}).fetch();
GoogleMaps.ready('exampleMap', function(map) {
// Add a marker to the map once it's ready
var k;
for(k in Users){
result = Users[k].Address;
var lat = Meteor.call("getLat", result);
var long = Meteor.call("getLong", result);
var marker = new google.maps.Marker({
position: new google.maps.LatLng(lat,long),
map: map.instance
});
}
});
Template.Map.onCreated(function() {
this.subscribe("storage");
});
`
Meteor Methods
Meteor.methods({
getLat: function(Address){
var geo = new GeoCoder();
var result = geo.geocode(Address);
console.log(result[0].latitude);
return result[0].latitude;
},
getLong: function(Address){
var geo = new GeoCoder();
var result = geo.geocode(Address);
console.log(result[0].longitude);
return result[0].longitude;
}
})`
GetLong: function (Address) {
var geo = new GeoCoder();
var Future = Npm.require('fibers/future');
// make some new future
var fut = new Future();
var message = geo.geocode(Address);
fut.return(message[0].latitude.toString());
// wait for something from the future
return fut.wait();
}
Interesting solution. I like your use of a method which appears to run on the server-side. I implemented a client-side solution, which would require processing before DB entry. I’ll probably be using your solution instead to ensure data integrity.
// Activate geocomplete on #main-test
Template.test.onRendered(function() {
this.autorun(function() {
// Wait for API to be loaded
if (GoogleMaps.loaded()) {
$('#location').geocomplete({
details: 'form',
detailsAttribute: 'data-geo'
});
}
});
});
The location ID is a form field that supports Google’s Places API for autocomplete. Here’s the HTML associated (it’s quite crude but works for a proof-of-concept)…
I noticed in your method, you’re retrieving a longitude, yet the code appears to be latitude. The address is being geocoded in var message but you’ll returning one parameter. I’m trying to get both long and lat back for storage and want it done in one method.
oh lol, thanks for pointing that out i hadn’t noticed
well, I use two different methods in mine…getLong and getLat… I’m sure you can do it a different way o.O don’t ask me how tho !
GetLong: function (Address) {
var geo = new GeoCoder();
var Future = Npm.require('fibers/future');
// make some new future
var fut = new Future();
var message = geo.geocode(Address);
fut.return(message[0].latitude.toString());
// wait for something from the future
return fut.wait();
},
GetLat: function (Address) {
var geo = new GeoCoder();
var Future = Npm.require('fibers/future');
// make some new future
var fut = new Future();
var message = geo.geocode(Address);
fut.return(message[0].longitude.toString());
// wait for something from the future
return fut.wait();
}
Yup, that’s what I’m implementing. It would still require 2 separate geocoding requests and I don’t think they get cached. This is a hit to the load time.
I’m actually unsure what would be the most appropriate method since I’m also new to Meteor. Maybe using a hook?
AutoForm.addHooks(['locationForm', 'anotherForm'], {
// Confirmation messages
onSuccess: function(operation, result, template) {
FlashMessages.sendSuccess('Success!');
// Router.go("/success");
},
// Populated the createdBy for DB
formToDoc: function(doc) {
// MAGIC HERE
var geoCode = GetGeo(doc.address);
doc.long = geoCode[0];
doc.lat = geoCode[1];
// Associate the user ID with the form
doc.createdBy = Meteor.userId();
return doc
},
});
A few notes about this…
I haven’t tested it
It runs client side
We might as well just use the places API to give us the lat/long if using autocomplete. This would fill 2 hidden fields as cited earlier: Google maps latitude returning undefined