I have got a strange problem with the JavaScript Geocode Api of Google Maps in AngularJS.
First of all I did some researches and I find out that I have to use the javascript callback function to get the formatted address out of a coordinate.
I implemented the callback function like this:
"use strict";
var getParcelApp = angular.module("getParcelApp", []);
function getStartAddress(latlng, callback) {
var geocoder = new google.maps.Geocoder;
geocoder.geocode({ 'location': latlng }, function(results, status) {
if (status === google.maps.GeocoderStatus.OK) {
callback(results[2].formatted_address); // HERE THE CALLBACK
}
});
};
var GetParcelAppController = function($scope, $http) {
$http.get("/umbraco/surface/ParcelSurface/GetLatLngParcel")
.success(function(result) {
$scope.coordinates = result;
$scope.getStartCoordinate();
})
.error(function(data) {
console.log(data);
});
$scope.getStartCoordinate = function() {
var latlng;
$scope.listOfCoordinates = [];
for (var i = 0; i < $scope.coordinates.length; i++) {
latlng = { lat: $scope.coordinates[i].Latitude, lng: $scope.coordinates[i].Longitude };
getStartAddress(latlng, function(formattedAddress) {
console.log(formattedAddress); // HERE formattedAddress WORKS
var coordinate = {
id: $scope.coordinates[i].Id,
waypointId: $scope.coordinates[i].WaypointId,
latitude: $scope.coordinates[i].Latitude,
longitude: $scope.coordinates[i].Longitude,
address: formattedAddress // HERE formattedAddress ISN'T WORKING
};
$scope.listOfCoordinates.push(coordinate);
});
}
console.log($scope.listOfCoordinates);
};
};
getParcelApp.controller("getParcelAppCtrl", GetParcelAppController);
As you may see I want an array of coordinate objects. But I really don't know why the console.log shows the right result and array is complete empty?
The Firefox console shows the following:
- The Array:
- Array [ ] getParcelController.js:45:9
- The formatted addresses:
- Mitte, Berlin, Deutschland getParcelController.js:34:17
- Innenstadt, Köln, Deutschland getParcelController.js:34:17
- Altstadt-Lehel, München, Deutschland getParcelController.js:34:17
- Mitte, Berlin, Deutschland getParcelController.js:34:17
- Innenstadt, Köln, Deutschland getParcelController.js:34:17
Do you have an idea why the console log is working properly and the array function isn't? If I write the array function outside of the callback function and without address: the array is created.
To be more detailed:
I want to show the formatted addresses of the coordinates in a select drop down box. This is defined in a html file as
<select id="getParcel" class="form-control"></select>
and i edited the getStartAddress call like the following:
$scope.getStartCoordinate = function() {
var latlng;
var selectBox = document.getElementById("getParcel");
$scope.listOfCoordinates = [];
for (var i = 0; i < $scope.coordinates.length; i++) {
latlng = { lat: $scope.coordinates[i].Latitude, lng: $scope.coordinates[i].Longitude };
getStartAddress(latlng, function(formattedAddress) {
var coordinate = {
id: $scope.coordinates[i].Id,
waypointId: $scope.coordinates[i].WaypointId,
latitude: $scope.coordinates[i].Latitude,
longitude: $scope.coordinates[i].Longitude,
address: formattedAddress
};
$scope.listOfCoordinates.push(coordinate);
console.log($scope.listOfCoordinates);
var selectElement = document.createElement("option");
selectElement.textContent = coordinate.address;
selectElement.value = coordinate.address;
selectBox.appendChild(selectElement);
});
}
};
I am really not an expert in javascript but in my understanding the function in getStartAddress is then called when the callback data are fetched? So the select drop down box should be filled with the addresses when the callback is finished, isn't it?
getStartAddressis anasynchronousfunction and you are logging$scope.listOfCoordinatesbefore it has fetched the data (and pushed it into the array). You have to do whatever you are doing inside the callback. Why Async JS programming "isn't working" is probably one of the most common questions on SO.getStartAddress. But I don't expected thatfunction(formattedAddress)is also asynchronous?function(formattedAddress)is the callback to the async function - it only gets executed after the data has been fetched.console.log($scope.listOfCoordinates)should show some results if I move it inside thefunction(formattedAddress), right? I moved it right under$scope.listOfCoordinates.push(coordinate);but nothing is logged. Even not a undefined or empty array.formattedAddressto be defined in your firstconsole.log(formattedAddress)and not be stored in yourcoordinateobject (which is then pushed onto your array).