Reputation: 21
I have a JSON object with some entries (Appointments) each thereof an "location id". Then I loop trough these entries and emit a request to my nodeJS server by socketIO to get data from document with the location id.
At the end I need an array with the data of lat/lng to create some marker on a map.
Here is the code:
//controller for showing map
.controller('MapCtrl', function($scope, socket){
socket.emit('getApp', staticUserid);
socket.on('getApps', function (appdata) {
var locArr = [];
for (var i = 0; i < appdata.length; i++) {
if (appdata[i].locationid != '') {
locArr.push(appdata[i].locationid);
}
}
var LatLngArr = [];
for (var j = 0; j < locArr.length; j++) {
socket.emit('getLocation', locArr[j]);
socket.on('getLoc', function (locData) {
console.log('received lat/lng: ' + locData.lat + '/' + locData.lng);
if (!LatLngArr[j]) LatLngArr[j] = []
LatLngArr[j][0] = locData.lat;
LatLngArr[j][1] = locData.lng;
});
}
//console.log('test:'+LatLngArr[0][0]);
});
var newMarkers = [[52.549678, 13.3879516],[52.5442992, 13.352809],[52.5186283,13.3761181]]; // this should be the generated array
var newCenter = [52.549678, 13.3879516];
createMap(newCenter,newMarkers);
})
The problem is, that the var LatLngArr isn't defined out of the...
socket.on('getLoc', function (locData)
It would be very nice if somebody can help me :-)
Thanks so much!
Upvotes: 0
Views: 81
Reputation: 4061
The reason why your code fails is because of the asynchronous nature of the line:
socket.on('getLoc', function (locData)
So LatLngArr
actually is defined when you register the callback, but it is not anymore at the time the callback is called. The reason for that is that JavaScript uses Closures.
You may have a look at this thread: How do JavaScript closures work?
Hence you have to wrap it in an IIFE. This way the function is executed immediately such that the value of j
behaves as you intended, because it is not longer referring to the j
of the outer scope.
Edit: A very nice explanation can be found in Item 13 of David Hermann's "Effective Javascript" – a book I totally can recommend. If you have problems understanding it, a look at this thread may help.
Upvotes: 0
Reputation: 1
If you can use Promises
.controller('MapCtrl', function($scope, socket){
socket.emit('getApp', staticUserid);
socket.on('getApps', function (appdata) {
var locArr = [];
for (var i = 0; i < appdata.length; i++) {
if (appdata[i].locationid != '') {
locArr.push(appdata[i].locationid);
}
}
var LatLngArr = [];
var promises = [];
for (var j = 0; j < locArr.length; j++) {
promises[j] = (function(captured_j) {
return new Promise(function(resolve, reject) {
socket.emit('getLocation', locArr[captured_j]);
socket.on('getLoc', function (locData) {
console.log('received lat/lng: ' + locData.lat + '/' + locData.lng);
if (!LatLngArr[captured_j]) LatLngArr[captured_j] = []
LatLngArr[captured_j][0] = locData.lat;
LatLngArr[captured_j][1] = locData.lng;
resolve({index: captured_j, result: LatLngArr[captured_j]});
});
});
}(j));
}
Promise.all(promises).then(function(arr) {
// ******************************************
// ******************************************
// arr is an array of {index: #, result [lat, lng]} - but you can also use LatLngArr
// ******************************************
// ******************************************
});
});
var newMarkers = [[52.549678, 13.3879516],[52.5442992, 13.352809],[52.5186283,13.3761181]]; // this should be the generated array
var newCenter = [52.549678, 13.3879516];
createMap(newCenter,newMarkers);
})
Upvotes: 1
Reputation: 1
try this
for (var j = 0; j < locArr.length; j++) {
(function(captured_j) {
socket.emit('getLocation', locArr[captured_j]);
socket.on('getLoc', function (locData) {
console.log('received lat/lng: ' + locData.lat + '/' + locData.lng);
if (!LatLngArr[captured_j]) LatLngArr[captured_j] = []
LatLngArr[captured_j][0] = locData.lat;
LatLngArr[captured_j][1] = locData.lng;
//
// the required result
//
if (j === 0) {
console.log('test:'+LatLngArr[0][0]);
}
//
});
}(j));
}
Upvotes: 0