Using Jade Array in Javascript transforms it to a string - javascript

I am passing an array of objects to my jade template, and want to use it as var in my js.
it seems to be transferred correctly, as
each level, i in stats
.levelStats
creates 4 divs (as expected)
now i have
script(type='text/javascript').
var statData = "!{stats}"
which, as far as i know, should load the data into a javascript var.
it does that, in a way...
console.log(statData);
// output: [object Object],[object Object],[object Object],[object Object]
// this means the correct data must be there..somewhere
console.log(typeof statData);
// output: string
what am I doing wrong?
how can i get the whole array into the var?
solution + lesson:
var foo = "!{bar}" makes the data a string (pretty obvious in restrospective)
right way to go: var foo = !{bar}

each level, i in stats
.levelStats
You are looping over (an array ?) stats where i is an index and level the element of your array at stats[i].
but you don't seem to use the elements separatly :
var statData = "!{stats}"
stats still the array, you will find each element in level !
Edit :
After clarification, to keep the whole array and set it to a variable :
var statData = !{JSON.stringify(stats)}

You need to put a string in the <script> tag. How to make array into a string, so that you can convert it back later? JSON.stringify.
So, something like this should work:
script.
var statData = !{JSON.stringify(stats)};

I spent full day to make it work. It is more advanced example, but we pass array to js in jade/pug file. Here we pass array of locations to google maps init script. Use it like this:
1)Prepare data on the server
JSON.stringify(locations = [
{ lat: -31.563910, lng: 147.154312 },
{ lat: -33.718234, lng: 150.363181 },
{ lat: 52.319277, lng: 21.000466 }
])
2)pass it to your pug/jade page.
There, use this with variable that you pass, for example: DATA_THAT_YOUPASS
script.
function initMap() {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 3,
center: {lat: 52.5191758, lng: 23.0002262}
});
// Create an array of alphabetical characters used to label the markers.
var labels = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
// Add some markers to the map.
// Note: The code uses the JavaScript Array.prototype.map() method to
// create an array of markers based on a given "locations" array.
// The map() method here has nothing to do with the Google Maps API.
var markers = locations.map(function(location, i) {
return new google.maps.Marker({
position: location,
label: labels[i % labels.length]
});
});
// Add a marker clusterer to manage the markers.
var markerCluster = new MarkerClusterer(map, markers,
{imagePath: 'https://developers.google.com/maps/documentation/javascript/examples/markerclusterer/m'});
}
var mydata = !{DATA_THAT_YOUPASS}
console.log(mydata);
console.log(mydata);
var locations = mydata;
#map
script(src='https://unpkg.com/#google/markerclustererplus#4.0.1/dist/markerclustererplus.min.js')
// Replace the value of the key parameter with your own API key.
script(async='', defer='', src='https://maps.googleapis.com/maps/api/js?key=XXXXXXXXXXXXXXXXXXXXXXXXXX&callback=initMap')

Related

Adding leaflet marker with nested array, getting Uncaught TypeError: Cannot read property 'lat' of null

I know this is a common error but I'm not seeing my specific problem. Doing a little basic JS practice and running into this error only when using a nested array of coordinate pairs. If I only try and map one single location the error goes away. Any thoughts as to why this might be happening? Code below.
var options = {
center: [39.8333,-98.5833],
zoom: 4
}
// instantiate the leaflet object
var map = L.map('map', options);
// Get basemap URL from Leaflet Providers
var basemap_url = 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}'
// Get basemap attributes from Leaflet Providers
var basemap_attributes = {
attribution: 'Tiles © Esri — Source: Esri, DeLorme, NAVTEQ, USGS, Intermap, iPC, NRCAN, Esri Japan, METI, Esri China (Hong Kong), Esri (Thailand), TomTom, 2012'
}
// Add tileset as a layer in our map by passing as arguments to tileLayer method
var tiles = L.tileLayer(basemap_url, basemap_attributes);
// add tiles to map with addLayer method
map.addLayer(tiles);
// variable to hold string value of cities
var cities = ["Victoria", "Bettles", "Truth or Consequences"];
var cityCoords = [
[48.430077, -123.353043],
[66.905857, -151.533330],
[33.1284, -107.25283]
];
var cityPops = [92141, 13, 5948];
var cityCapitals = [true, false, false];
// loop through all the elements in the cities array
for(let i = 0; i <= cities.length; i++){
let cityName = cities[i];
let cityPop = cityPops[i];
let cityCap = cityCapitals[i];
let namePop = `<b>${cityName}</b><br> population: <b>${cityPop}</b><br>`;
let popup = `${cityName} population: ${cityPop}`
console.log(popup)
if (cityCap == true) {
popup += 'is a capital city'}
L.marker(cityCoords).addTo(map)
.bindPopup(popup);
}
As commented, replacing
L.marker(cityCoords).addTo(map)
with
L.marker(cityCoords[i]).addTo(map)
solves the problem by passing a LatLng array of numbers to marker as covered in documentation.
I deduce that Leaflet converts an array of arrays to null if the array should have contained numeric coordinate values, and then generates errors trying to access lat or lng properties of what should have been a valid conversion result.

Loop for new Google Map Marker for every JSON object in database

I'm working with a friend to create a Google Map marker for every entry in a table - I have a loop but I'm not sure I've got it right. The map works fine, I can add normal markers and can loop through the entries and append them to a div but when I try to use the marker code in the loop I get the following errors for every entry in the console:
InvalidValueError: setPosition: not a LatLng or LatLngLiteral: in property lat: not a number
InvalidValueError: setMap: not an instance of Map; and not an instance of StreetViewPanorama
Does this mean that the database isn't saving the lat/long as a number? Here is a shorter version of the code I'm using:
$.ajax({
type: 'POST',
url: 'getAllJson.php',
success: function(jsonData) {
var obj = (jsonData);
$.each(obj, function(key,value) {
//console.log(key, first, value[1], value[2]);
var user = {
id: value["id"],
firstName: value["first_name"],
lastName: value["last_name"],
email: value["email"],
lat: value["latitude"],
long: value["longitude"]
};
var firstName = user.firstName,
lastName = user.lastName,
email = user.email,
userLat = user.lat,
userLong = user.long;
// marker
var markerLatLng = {lat: userLat, lng: userLong};
var marker = new google.maps.Marker({
position: markerLatLng,
map: map
});
});
}
});
Am I on the right track or is there a better/easier way to loop through all the entries and create a marker based on the lat/long? Thanks!
You have to solve two problems here.
The first is to parse userLat/ userLong to floats. This can be done as mentioned above in my comment:
var markerLatLng = {lat: parseFloat(userLat), lng: parseFloat(userLong)};
The other Problem you are facing is, that you map instance isn´t reachable, because you have defined it locally in initMap. To fix this, you simply make
var map;
function mapInit(){
map = new google.maps.Map('');
}
This should do it.

Google Map markers and JSON object

I have a database which stores the position of markers previously added on the Google Map (Latitude/Longitude). What I want to do now, it's to create a function which takes a JSON object as a parameter, containing those markers position and add automatically the markers in the map. I start to get the markers from my database and try to loop on the JSON object which looks like this:
{"markers":"\"[{\\\"k\\\":48.80686346108517,\\\"B\\\":1.494140625},{\\\"k\\\":50.28933925329177,\\\"B\\\":14.326171875},{\\\"k\\\":43.70759350405294,\\\"B\\\":21.357421875},{\\\"k\\\":30.977609093348686,\\\"B\\\":11.337890625},{\\\"k\\\":40.58058466412761,\\\"B\\\":-0.87890625},{\\\"k\\\":48.45835188280866,\\\"B\\\":1.318359375}]\""}
Here is the current state of my code:
//Create a new set of markers based on received position.
function createMarkerBasedOnFetchedPosition(fetchedMarkersPosition)
{
var jsonData = JSON.parse(fetchedMarkersPosition);
alert(fetchedMarkersPosition);
map.addMarker({
lat: ? //Fetched from the JSON object parsing.
lng: ? //Fetched from the JSON object parsing.
animation: google.maps.Animation.DROP
});
Can anyone please help me to build this, I don't know yet how to deal with a JSON object to retrieve the Latitude/Longitude. I'm looking for a JavaScript solution only. Thanks for your help!
From your current code you would then need to loop through the markers with a for loop like so and add a marker to the map:
var data = '{"markers":[{"k":48.80686346108517,"B":1.494140625},{"k":50.28933925329177,"B":14.326171875},{"k":43.70759350405294,"B":21.357421875},{"k":30.977609093348686,"B":11.337890625},{"k":40.58058466412761,"B":-0.87890625},{"k":48.45835188280866,"B":1.318359375}]}';
function createMarkerBasedOnFetchedPosition(fetchedMarkersPosition)
{
var jsonData = JSON.parse(fetchedMarkersPosition);
for (var i = 0; i < jsonData.markers.length; i++) {
map.addMarker({
lat: jsonData.markers[i].k,
lng: jsonData.markers[i].b,
animation: google.maps.Animation.DROP
});
}
}
createMarkerBasedOnFetchedPosition(data);

Integrate Google Map with Markers from HTTPrequest Javascript

Hi there I am Using appcelerator, and I want to integrate a map with an array of markers I am getting from a HTTPRequest...
I am effing lost, totally lost.
This is how the map looks like:
var mapview = Titanium.Map.createView({
mapType: Titanium.Map.STANDARD_TYPE,
region: {latitude:33.74511, longitude:-84.38993,
latitudeDelta:0.01, longitudeDelta:0.01},
animate:true,
regionFit:true,
userLocation:true,
annotations:[mountainView]
});
And I have the example of 1 marker hardcoded ...
var mountainView = Titanium.Map.createAnnotation({
latitude:37.390749,
longitude:-122.081651,
title:"Appcelerator Headquarters",
subtitle:'Mountain View, CA',
pincolor:Titanium.Map.ANNOTATION_RED,
animate:true,
leftButton: '../images/appcelerator_small.png',
myid:1 // CUSTOM ATTRIBUTE THAT IS PASSED INTO EVENT OBJECTS
});
So yo create the marker and in the annotations section you add it to the map, the thing here is that I am getting the markers from this:
var url = "http://myURLwithMyParameters";
var xhr = Ti.Network.createHTTPClient({
onload: function(e) {
// this function is called when data is returned from the server and available for use
// this.responseText holds the raw text return of the message (used for text/JSON)
var result = this.responseText;
var xml = Ti.XML.parseString(result);
var items = xml.documentElement.getElementsByTagName("marker");
var name = xml.documentElement.getElementsByTagName("name");
var value = xml.documentElement.getElementsByTagName("address");
var data = [];
for (var i=0;i<items.length;i++) {
data.push({
name: items.item[i].getElementsByTagName("name")[0].textContent,
address: items.item[i].getElementsByTagName("address")[0].textContent
})
Does any one know how to integrate this?
I think I must build the map in the same function as the markers, but I've tried several options and haven't found ANY example of this in the web.
Any clue would be very appreciated.
Thank you in advance.
If all you have is an address, you'll need to forward geocode those addresses to get lat/long coordinates. Those coords are required to place annotations on the map. Check the docs at forwardGeocoder(). There's an example in the KitchenSink

Multiple markers not showing in Google Maps with Javascript API v3?

I'd like to know how to put multiple markers for Google Maps using Javascript API v3.
I tried the solution posted here, but it does not work for me for some reason:
var directionDisplay;
function initialize() {
var myOptions = { zoom: 9, center: new google.maps.LatLng(40.81940575,-73.95647955), mapTypeId: google.maps.MapTypeId.TERRAIN }
var map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
setMarkers(map, properties);
var properties = [
['106 Ft Washington Avenue',40.8388485,-73.9436015,'Mjg4'],
];
function setMarkers(map, buildings) {
var image = new google.maps.MarkerImage('map_marker.png', new google.maps.Size(19,32), new google.maps.Point(0,0), new google.maps.Point(10,32));
var shadow = new google.maps.MarkerImage('map_marker_shadow.png', new google.maps.Size(28,32), new google.maps.Point(0,0), new google.maps.Point(10,32));
var bounds = new google.maps.LatLngBounds;
for (var i in buildings) {
var myLatLng = new google.maps.LatLng(buildings[i][1], buildings[i][2]);
bounds.extend(myLatLng);
var marker = new google.maps.Marker({ position: myLatLng, map: map, shadow: shadow, icon: image, title: buildings[i][0] });
google.maps.event.addListener(marker, 'click', function() { window.location = ('detail?b=' + buildings[i][3]); });
}
map.fitBounds(bounds);
}
}
</script>
Could anyone kindly explain why this doesn't work for me?
This question is already a few months old, but I noticed that it remained unanswered. I guess the OP already found a way through this, but let me attempt an answer for the sake of completeness.
I can spot a few major problems in your code above:
First of all, you are trying to pass the properties array to the setMarkers() function, before properties is defined. Therefore setMarkers() will receive undefined for the second argument, which is why nothing is showing on your map.
Then, you are having a very common closure problem in that for in loop. Variables enclosed in a closure share the same single environment, so by the time the click callback from the addListener is called, the loop will have run its course and the i variable will be left pointing to the last value it had when loop ended.
In addition, you have a dangling comma in the array literal, which can cause a syntax error in some browsers.
To fix the first problem, simply define the properties array before calling setMarkers():
var properties = [
['106 Ft Washington Avenue',40.8388485,-73.9436015,'Mjg4'],
];
setMarkers(map, properties);
You can then solve the closure problem with even more closures, using a function factory:
function makeClickCallback(buildings, i) {
return function() {
window.location = ('detail?b=' + buildings[i][3]);
};
}
for (var i in buildings) {
// ...
google.maps.event.addListener(marker, 'click',
makeClickCallback(buildings, i);
}
This can be quite a tricky topic, if you are not familiar with how closures work. You may to check out the following Mozilla article for a brief introduction:
Working with Closures
Then you may want to make sure to remove the dangling comma in your array literal:
var properties = [
['106 Ft Washington Avenue',40.8388485,-73.9436015,'Mjg4'] // no comma
];
In addition, note that since there is just one element in your properties array, you will only get one marker on the map. I'm not sure if the other elements were removed for the sake of this example, but if it wasn't, simply add more locations like this:
var properties = [
['106 Ft Washington Avenue',40.8388485,-73.9436015,'Mjg4'],
['Another Location',50.505050,-75.505050,'Mjg5']
];

Categories