Deeper understanding of Promises - javascript

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 ?

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()

Related

Filter doesnt work on long string addresses

I am trying to build a little filtering tool in lightening web components and I can filter perfectly by the name but it fails if I try filtering by the billing address(state, city or country)
Returned API data looks like this
[
{
"Id": "001IY000002QarYYAS",
"Name": "Bertha Lee",
"BillingStreet": "22 Fifo Street",
"BillingCity": "Sunshine",
"BillingCountry": "Australia"
},
{
"Id": "001IY000002QV8nYAG",
"Name": "Sample Account for Entitlements"
},
{
"Id": "001IY000002QV8bYAG",
"Name": "Edge Communications",
"BillingStreet": "312 Constitution Place\nAustin, TX 78767\nUSA",
"BillingCity": "Austin"
},
{
"Id": "001IY000002QV8cYAG",
"Name": "Burlington Textiles Corp of America",
"BillingStreet": "525 S. Lexington Ave",
"BillingCity": "Burlington",
"BillingCountry": "USA"
},
{
"Id": "001IY000002QV8dYAG",
"Name": "Pyramid Construction Inc.",
"BillingStreet": "2 Place Jussieu",
"BillingCity": "Paris",
"BillingCountry": "France"
},
{
"Id": "001IY000002QV8eYAG",
"Name": "Dickenson plc",
"BillingStreet": "1301 Hoch Drive",
"BillingCity": "Lawrence",
"BillingCountry": "USA"
},
{
"Id": "001IY000002QV8fYAG",
"Name": "Grand Hotels & Resorts Ltd",
"BillingStreet": "2334 N. Michigan Avenue, Suite 1500\nChicago, IL 60601, USA",
"BillingCity": "Chicago"
},
{
"Id": "001IY000002QV8gYAG",
"Name": "United Oil & Gas Corp.",
"BillingStreet": "1301 Avenue of the Americas \nNew York, NY 10019\nUSA",
"BillingCity": "New York"
},
{
"Id": "001IY000002QV8hYAG",
"Name": "Express Logistics and Transport",
"BillingStreet": "620 SW 5th Avenue Suite 400\nPortland, Oregon 97204\nUnited States",
"BillingCity": "Portland"
},
{
"Id": "001IY000002QV8iYAG",
"Name": "University of Arizona",
"BillingStreet": "888 N Euclid \nHallis Center, Room 501\nTucson, AZ 85721\nUnited States",
"BillingCity": "Tucson"
}
]
Javascript code to manipulate data and push to my html
export default class Accountsfilter extends LightningElement {
availableAccounts;
error;
columns = columns;
searchString;
initialRecords;
#wire( fetchAccounts )
wiredAccount( { error, data } ) {
if ( data ) {
this.availableAccounts = JSON.parse(JSON.stringify(data));
console.log(this.availableAccounts);
this.initialRecords = JSON.parse(JSON.stringify(data));
this.error = undefined;
} else if ( error ) {
this.error = error;
this.availableAccounts = undefined;
}
}
handleSearch( event ) {
const searchKey = event?.target?.value.toLowerCase();
console.log(searchKey)
if ( searchKey ) {
console.log(searchKey)
this.availableAccounts = this.initialRecords;
if ( this.availableAccounts ) {
let recs = []
recs.concat(this.availableAccounts.filter(x => x?.BillingCity.toLowerCase().includes(searchKey)))
this.availableAccounts = recs
}
} else {
this.availableAccounts = this.initialRecords;
}
}
}
In the code above I use billing city and it fails. I wanna be able to filter using billingstreet, city and country

Query JSON data sharing same value

Sample JSON Data:
{
"results": [
{
"name": "John Smith",
"state": "NY",
"phone": "555-555-1111"
},
{
"name": "Mary Jones",
"state": "PA",
"phone": "555-555-2222"
},
{
"name": "Edward Edwards",
"state": "NY",
"phone": "555-555-3333"
},
{
"name": "Abby Abberson",
"state": "RI",
"phone": "555-555-4444"
},
]}
With this sample data I can display individual values from the results [] array with object.name and object.phone to look something like:
John Smith 555-555-1111<br />
Mary Jones 555-555-2222<br />
Edward Edwards 555-555-3333<br />
Abby Abberson 555-555-4444
What I am trying to do now is select just the people who's state value is NY and only display their object.name and object.phone:
John Smith 555-555-1111<br />
Edward Edwards 555-555-3333
I tried this lovely little block but all it did was print all the names, which makes sense after I tried it.
if (object.state = "NY") {
div.append(repName);
}
I can't seem to think of a way to only display those that share a the same state.
I'm probably searching for the wrong terms or have to go about this another way... please help!
You are using =(assignment operator),which is wrong.
You have to use ==(comparison operator)
So do like below:-
if (object.state == "NY") {
div.append(repName);
}
Working sample-
var obj = {
"results": [
{
"name": "John Smith",
"state": "NY",
"phone": "555-555-1111"
},
{
"name": "Mary Jones",
"state": "PA",
"phone": "555-555-2222"
},
{
"name": "Edward Edwards",
"state": "NY",
"phone": "555-555-3333"
},
{
"name": "Abby Abberson",
"state": "RI",
"phone": "555-555-4444"
},
]};
$(obj.results).each(function(k,object){
if (object.state == "NY") {
$('#final_data').append(object.name +" : "+object.phone+"<br/>");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="final_data"></div>
My one cent solution:
var obj = {
"results": [
{
"name": "John Smith",
"state": "NY",
"phone": "555-555-1111"
},
{
"name": "Mary Jones",
"state": "PA",
"phone": "555-555-2222"
},
{
"name": "Edward Edwards",
"state": "NY",
"phone": "555-555-3333"
},
{
"name": "Abby Abberson",
"state": "RI",
"phone": "555-555-4444"
},
]};
obj.results.forEach((value) => {
if (value.state === "NY") {
const li = document.createElement("li");
li.innerHTML = `${value.name} : ${value.phone}`;
document.querySelector("#final_data").appendChild(li);
}
});
<ul id="final_data"></ul>
Like Alive said you used the assignment operator = instead of comparison operator === or ==.

Nested Object array values

I am utilizing jquery to loop thru 'searchResults' and looping thru 'SearchResult' and then looping again into 'SearchResultItems' to begin appending values. I then locate 'LocationDetails' and loop thru the nested values of State to display states for each 'DisplayTitle'.
If that description isn't well written, here is the code.
searchResults = [{
"SearchResult": {
"SearchResultItems": [{
"MatchedObjectDescriptor": {
"URI":"http://...",
"DisplayTitle": "Boss Person",
"LocationDetails": [{
"State": "California",
"CityName": "San Francisco County, California",
},{
"State": "Colorado",
"LocationName": "Denver, Colorado",
},{
"State": "California",
"CityName": "Los Angeles, California",
}]
}
},{
"MatchedObjectDescriptor": {
"URI":"http://...",
"DisplayTitle": "Assistant",
"LocationDetails": [{
"State": "Colorado",
"CityName": "Denver, Colorado",
},{
"State": "Colorado",
"LocationName": "Denver, Colorado",
},{
"State": "California",
"CityName": "Sacramento, California",
}]
}
},
]
}
}];
My current attempt at navigating the array of objects.
$.each(searchResults, function(key,value){
$.each(value.SearchResult.SearchResultItems,function(key,value){
var items = value.MatchedObjectDescriptor,
title = items.DisplayTitle;
$.each(items.LocationDetails, function(key,value){
var states = value.State;
$(".content").append("<ul><li>'" + title + "'<ul><li>'" + states + "'</li></ul></li></ul>");
});
});
});
See my work here so far with the wrong output: https://jsfiddle.net/arkjoseph/esvgcos7/15/
I am looking for this output filtering duplicate states and not having a different title for each state that is available in the object.
Boss person
California
Colorado
Assistant
Colorado
California
This gives you expected output.
searchResults = [{
"SearchResult": {
"SearchResultItems": [{
"MatchedObjectDescriptor": {
"URI": "http://...",
"DisplayTitle": "Boss Person",
"LocationDetails": [{
"State": "California",
"CityName": "San Francisco County, California",
}, {
"State": "Colorado",
"LocationName": "Denver, Colorado",
}, {
"State": "California",
"CityName": "Los Angeles, California",
}]
}
}, {
"MatchedObjectDescriptor": {
"URI": "http://...",
"DisplayTitle": "Assistant",
"LocationDetails": [{
"State": "Colorado",
"CityName": "Denver, Colorado",
}, {
"State": "Colorado",
"LocationName": "Denver, Colorado",
}, {
"State": "California",
"CityName": "Sacramento, California",
}]
}
}, ]
}
}];
var states = "";
$.each(searchResults, function(key, value) {
$.each(value.SearchResult.SearchResultItems, function(key, value) {
var items = value.MatchedObjectDescriptor,
title = items.DisplayTitle;
var s = [];
var li = "";
$.each(items.LocationDetails, function(key, value) {
var states = value.State;
if (!s.includes(states)) {
s.push(states);
li += ("<li>" + states + "</li>")
}
});
$(".content").append("<ul><li>" + title + "<ul>" + li + "</ul></li></ul>");
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<div class="content"></div>
actual json endpoint: <a target="_blank" href="https://pastebin.com/embed_js/dRfMedYb">Here</a>
A working version of your code is as follows. This is just one example of how to do it, but using Set in ES6 (if you have an environment where it's permitted or are using a transpiler like Babel) might be desirable. Either way, this just appends to an array and joins on an empty string at the end to create your nodes. Using jQuery to build your elements also will likely be more scalable down the road, but for a small app the following works.
searchResults = [{
"SearchResult": {
"SearchResultItems": [{
"MatchedObjectDescriptor": {
"URI":"http://...",
"DisplayTitle": "Boss Person",
"LocationDetails": [{
"State": "California",
"CityName": "San Francisco County, California",
},{
"State": "Colorado",
"LocationName": "Denver, Colorado",
},{
"State": "California",
"CityName": "Los Angeles, California",
}]
}
},{
"MatchedObjectDescriptor": {
"URI":"http://...",
"DisplayTitle": "Assistant",
"LocationDetails": [{
"State": "Colorado",
"CityName": "Denver, Colorado",
},{
"State": "Colorado",
"LocationName": "Denver, Colorado",
},{
"State": "California",
"CityName": "Sacramento, California",
}]
}
},
]
}
}];
var states = [];
var output = [];
$.each(searchResults, function(key,value){
output.push("<ul>")
$.each(value.SearchResult.SearchResultItems,function(key,value){
var items = value.MatchedObjectDescriptor,
title = items.DisplayTitle;
output.push("<li>" + title + "</li>")
output.push("<ul>")
$.each(items.LocationDetails, function(key,value){
if (states.filter(s => s == value.State).length) return;
states.push(value.State)
output.push("<li>" + value.State + "</li>")
});
states = []
output.push("</ul>")
});
output.push('</ul>')
});
$(".content").append(output.join(''));

number of addresses in JSON?

I have the following JSON (which I validated and verified is correct) and I'm trying to get the number of addresses.
When I do a
var location = req.body;
I get
{ AddressValidateRequest:
{ '-USERID': 'xxxxxxxxxxx',
Address: [ [Object], [Object], [Object] ] } }
How do I get the number of addresses?
{
"AddressValidateRequest": {
"-USERID": "xxxxxxxxxxx",
"Address": [
{
"-ID": "0",
"FirmName": "firmname",
"Address1": "address1here",
"Address2": "13 infinite loop",
"City": "new york",
"State": "NY",
"Zip5": "zip5here",
"Zip4": "zip4here"
},
{
"-ID": "1",
"FirmName": "firmhere",
"Address1": "address1here",
"Address2": "1 Smith Ct ",
"City": "San Predo",
"State": "CA",
"Zip5": "ziphere",
"Zip4": "ziphere1"
},
{
"-ID": "1",
"FirmName": "firmhere",
"Address1": "address1here",
"Address2": "12 John Rd ",
"City": "Newark",
"State": "PA",
"Zip5": "ziphere",
"Zip4": "ziphere1"
}
]
}
}
This should do it
req.body.AddressValidateRequest.Address.length
To get a specific address, (e.g., the first)
req.body.AddressValidateRequest.Address[0]
To get a field on an address
req.body.AddressValidateRequest.Address[0].City
// "New York"

jQuery .each display array data - cannot work it out

I'm trying to loop through all this array data but it won't work out how to display it all via jquery using the .each function? Can someone help me out?
ARRAY:
{
"ListOrdersResult": {
"Orders": {
"Order": [
{
"ShipmentServiceLevelCategory": "Standard",
"OrderTotal": {
"Amount": "29.00",
"CurrencyCode": "GBP"
},
"ShipServiceLevel": "Std UK Dom",
"LatestShipDate": "2013-11-28T23:59:59Z",
"MarketplaceId": "A1F83G8C2ARO7P",
"SalesChannel": "Amazon.co.uk",
"ShippingAddress": {
"Phone": "0800 000 0000",
"PostalCode": "A11 H11",
"Name": "stephanie ross",
"CountryCode": "GB",
"StateOrRegion": "regiion",
"AddressLine2": "cairnbulg",
"AddressLine1": "loco 2222 name",
"City": "fraserburgh"
},
"ShippedByAmazonTFM": "false",
"OrderType": "StandardOrder",
"FulfillmentChannel": "MFN",
"BuyerEmail": "c9tkdmn724jpgkd#blahblah.com",
"OrderStatus": "Shipped",
"BuyerName": "custom A Ross",
"LastUpdateDate": "2013-11-27T14:26:53Z",
"EarliestShipDate": "2013-11-27T00:00:00Z",
"PurchaseDate": "2013-11-26T22:25:39Z",
"NumberOfItemsUnshipped": "0",
"AmazonOrderId": "205-8108202-4976362",
"NumberOfItemsShipped": "1",
"PaymentMethod": "Other"
},
{
"ShipmentServiceLevelCategory": "Standard",
"OrderTotal": {
"Amount": "29.00",
"CurrencyCode": "GBP"
},
"ShipServiceLevel": "Std UK Dom",
"LatestShipDate": "2013-11-28T23:59:59Z",
"MarketplaceId": "A1F83G8C2ARO7P",
"SalesChannel": "Amazon.co.uk",
"ShippingAddress": {
"Phone": "0800 000 0000",
"PostalCode": "A11 H11",
"Name": "stephanie ross",
"CountryCode": "GB",
"StateOrRegion": "regiion",
"AddressLine2": "cairnbulg",
"AddressLine1": "loco 2222 name",
"City": "fraserburgh"
},
"ShippedByAmazonTFM": "false",
"OrderType": "StandardOrder",
"FulfillmentChannel": "MFN",
"BuyerEmail": "c9tkdmn724jpgkd#blahblah.com",
"OrderStatus": "Shipped",
"BuyerName": "custom A Ross",
"LastUpdateDate": "2013-11-27T14:26:53Z",
"EarliestShipDate": "2013-11-27T00:00:00Z",
"PurchaseDate": "2013-11-26T22:25:39Z",
"NumberOfItemsUnshipped": "0",
"AmazonOrderId": "205-8108202-4976362",
"NumberOfItemsShipped": "1",
"PaymentMethod": "Other"
}
]
},
"CreatedBefore": "2014-05-14T01:12:05Z"
},
"ResponseMetadata": {
"RequestId": "46f5c980-91e6-44d3-bc9d-668976855862"
},
"xmlns": "https://mws.amazonservices.com/Orders/2011-01-01"
}
CURRENT JS:
$(document).ready(function(){
$.get('functions/ListOrders.php', function(xml){
var newOrders = $.xml2json(xml);
$.each(newOrders.Orders.Order, function(index, value) {
console.log(value);
console.log(value.ShipmentServiceLevelCategory);
});
$('body').text(JSON.stringify(newOrders));
});
});
You are missing the first element of the JSON object:
Change
$.each(newOrders.Orders.Order, function(index, value) {
To
$.each(newOrders.ListOrdersResult.Orders.Order, function(index, value) {
Demo:
http://jsfiddle.net/9YU3H/

Categories