MegaRacer MegaRacer - 14 days ago 7
Javascript Question

Deeper understanding of Promises

In my controller, I have a branches array in which I need to append location object containing lat long to each item of it i.e.

{
"BANK": "B N P PARIBAS",
"IFSC": "BNPA0009009",
"MICR CODE": "400034002",
"BRANCH": "MUMBAI",
"ADDRESS": "FRENCH BANK BLDG.,62, HOMJI STREET, MUMBAI - 400 001",
"CONTACT": "0",
"CITY": "MUMBAI",
"DISTRICT": "MUMBAI",
"STATE": "MAHARASHTRA",
"ZIPCODE": "400 001",
"location": {
lat: ,
long:
}
},


I am doing so by iterating the branches vi angular forEach and calling the getLatLong function on each item inside forEach loop.

However, the control/execution of the function is such that it return deferred.promise before I have got any results from service call. Ideally I want to have the location object from google maps API and then when it resolves I want the results back to controller function getLatLong and return that location object which in turn be assigned to item.location in forEach loop.

My controller

module.exports = function(AppFactory, $q){
'use strict';

let ctrl = this;
ctrl.showList = true;
ctrl.branches = [
{
"BANK": "B N P PARIBAS",
"IFSC": "BNPA0009008",
"MICR CODE": "700034002",
"BRANCH": "KOLKATA",
"ADDRESS": "UNIT NO. 301, OFFICE NO. 2, 3RD FLOOR, AVANI SIGNATURE,91A/1, PARK STREET,KOLKATA :- 700016",
"CONTACT": "0",
"CITY": "KOLKATA",
"DISTRICT": "KOLKATA",
"STATE": "WEST BENGAL",
"ZIPCODE": "700016"

},
{
"BANK": "B N P PARIBAS",
"IFSC": "BNPA0009009",
"MICR CODE": "400034002",
"BRANCH": "MUMBAI",
"ADDRESS": "FRENCH BANK BLDG.,62, HOMJI STREET, MUMBAI - 400 001",
"CONTACT": "0",
"CITY": "MUMBAI",
"DISTRICT": "MUMBAI",
"STATE": "MAHARASHTRA",
"ZIPCODE": "400 001"
},
{
"BANK": "B N P PARIBAS",
"IFSC": "BNPA0009065",
"MICR CODE": "110034002",
"BRANCH": "DELHI",
"ADDRESS": "1ST FLOOR EAST TOWER (SOOD TOWER), 25, BARAKHAMBA ROAD,NEW DELHI :- 110001",
"CONTACT": "0",
"CITY": "DELHI",
"DISTRICT": "DELHI",
"STATE": "DELHI",
"ZIPCODE": "110001"
},
{
"BANK": "B N P PARIBAS",
"IFSC": "BNPA0009067",
"MICR CODE": "560034002",
"BRANCH": "BANGALORE",
"ADDRESS": "3RD FL,LANDMARK,21/15,M.G.ROAD,BANGLORE-560 001",
"CONTACT": "0",
"CITY": "BANGALORE",
"DISTRICT": "BANGALORE",
"STATE": "KARNATAKA",
"ZIPCODE": "560 001"
},
{
"BANK": "B N P PARIBAS",
"IFSC": "BNPA0009069",
"MICR CODE": "411034002",
"BRANCH": "PUNE",
"ADDRESS": "5 & 6,GODREJ MILLENIUM PARK,9,KOREGAON ROAD,PUNE-411 001",
"CONTACT": "0",
"CITY": "PUNE",
"DISTRICT": "PUNE",
"STATE": "MAHARASHTRA",
"ZIPCODE": "411 001"
}
]


// console.log(ctrl.branches);
function getLatLong(addressOrZip){

let results;
let deferred = $q.defer();
AppFactory.getLatLong(addressOrZip).then(function(res){
console.log(res);
deferred.resolve(res);
// if(res.results.length > 0){
// results = res.results[0].geometry.location;
// }else{
// results = res.results;
// }
// return results;
}, function(error){
deferred.reject(res);
});

return deferred.promise;

}

ctrl.toggleViews = function(){
ctrl.showList = !ctrl.showList;

if(!ctrl.showList){
angular.forEach(ctrl.branches, function(item){
let location = getLatLong(item.ZIPCODE );
console.log(location);
// let location = getLatLong( item.ADDRESS || item.ZIPCODE );

// if(location){
// item.location = location;
// }
})

console.log("Logging branches with location object...");

console.log(ctrl.branches);
}
}


}

Then in my AppFactory

let getLatLong = function(location){
// let defferred = $q.defer();
return $http({
url: "https://maps.googleapis.com/maps/api/geocode/json?address="+ location +"&key=AIzaSyDGyOrnNj8rrRFR92m6BEMvR24JiYoHtMs"
}).then(function(response){
return response.data;
// defferred.resolve(response.data);
}, function(error){
return error;
// defferred.reject(error);
});

// return defferred.promise;
}


How can I get around this ?

Answer

getLatLong() returns a promise (which is what $http returns) so you need to use then() on that returned promise to access the response data

Change:

let location = getLatLong(item.ZIPCODE );
console.log(location);

To:

getLatLong(item.ZIPCODE ).then(function(data){
    item.location = data;
    console.log(item.location);
});

Will leave it up to you to validate that error is not returned to this then()

Comments