Deleting URL parameters using URLSearchParams - javascript

I'm utilizing the URLSearchParams API to delete keys/values from the query string in my URL.
I have the following snippet:
params = new URLSearchParams('a=x&b=y&c=z');
params.forEach(function(value, key){
console.log("Deleted: ", key, value, params.toString());
params.delete(key);
});
console.log("Left with: ", params.toString());
Invariably, the Left with: returns part of the query parameters.
Output on this JSFiddle:
☁️ "Running fiddle"
"Deleted: ", "a", "x", "a=x&b=y&c=z"
"Deleted: ", "c", "z", "b=y&c=z"
"Left with", "b=y"
My understanding of forEach() is that it'll loop over all the key/value pairs, but based on this fiddle, it looks like it exits the loop on the penultimate pair.
Edit, based on feedback in the comments below:
I'm trying to selectively retain one or two parameters (based on a list provided).
params = new URLSearchParams('a=x&b=y&c=z&d=1');
params.forEach(function(value, key){
retainList = ['d'];
if (retainList.includes(key)){
console.log("Retaining ", key);
} else {
console.log("Deleted: ", key, value, params.toString());
params.delete(key);
}
});
console.log("Left with: ", params.toString());

Seems to be some odd reference issue happening with URLSearchParams. Even when you use the .keys() method to get a list of keys it seems like it's giving a reference to it's internal list of keys.
You can work around this issue by cloning the list of keys using spread
params = new URLSearchParams('a=x&b=y&c=z');
keys = [...params.keys()]
for (key of keys) {
console.log("Deleting: ", key, params.get(key), params.toString());
params.delete(key)
};
console.log("Left with: ", params.toString());
To achieve the desired result you could do:
params = new URLSearchParams('a=x&b=y&c=z&d=1');
retainList = ['d']
for (key of [...params.keys()]) {
if (! retainList.includes(key)) {
console.log("Deleting: ", key, params.get(key), params.toString());
params.delete(key)
}
};
console.log("Left with: ", params.toString());

Related

Complex JSON obj and jQuery or Javascript map to specific key, value

I am banging my head trying to figure this out. And it should not be this hard. I am obviously missing a step.
I am pulling data from: openaq.org
The object I get back is based on a JSON object.
For now, I am using jQuery to parse the object and I am getting to the sub portion of the object that hold the specific parameter I want but I can't get to the specific key,value pair.
The object does not come back in the same order all the time. So when I tried to originally set up my call I did something like
obj.results.measurements[0].
Well since the obj can come back in an random order, I went back to find the key,value pair again and it was the wrong value, throwing my visual off.
That said, I have looked at use jQuery's find() on JSON object and for some reason can not get what I need from the object I am given by openaq.org.
One version of the object looks like this:
{"meta":{"name":"openaq-api","license":"CC BY 4.0d","website":"https://u50g7n0cbj.execute-api.us-east-1.amazonaws.com/","page":1,"limit":100,"found":1},"results":[{"location":"Metro Lofts","city":null,"country":"US","coordinates":{"latitude":39.731,"longitude":-104.9888},"measurements":[{"parameter":"pm10","value":49.9,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"pm1","value":24,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"um100","value":0,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um025","value":0.28,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um010","value":4.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"pm25","value":41.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"}]}]}
I am trying to get the "pm25" value.
The code I have tried is this:
function getAirQualityJson(){
$.ajax({
url: 'https://api.openaq.org/v2/latest?coordinates=39.73915,-104.9847',
type: 'GET',
dataType: "json"
// data: data ,
}).done(function(json){
console.log("the json is" + JSON.stringify(json));
console.log("the json internal is" + JSON.stringify(json.results));
var obj = json.results;
var pm25 = "";
//console.log(JSON.stringify(json.results.measurements[0]["parameter"]));
$.each(json.results[0], function(i,items){
//console.log("obj item:" + JSON.stringify(obj[0].measurements));
$.each(obj[0].measurements, function(y,things){
//console.log("each measurement:" + JSON.stringify(obj[0].measurements[0].value));//get each measurement
//pm 2.5
//Can come back in random order, get value from the key "pm25"
// pm25 = JSON.stringify(obj[0].measurements[2].value);
pm25 = JSON.stringify(obj[0].measurements[0].value);
console.log("pm25 is: " + pm25); // not right
});
});
//Trying Grep and map below too. Not working
jQuery.map(obj, function(objThing)
{ console.log("map it 1:" + JSON.stringify(objThing.measurements.parameter));
if(objThing.measurements.parameter === "pm25"){
// return objThing; // or return obj.name, whatever.
console.log("map it:" + objThing);
}else{
console.log("in else for pm25 map");
}
});
jQuery.grep(obj, function(otherObj) {
//return otherObj.parameter === "pm25";
console.log("Grep it" + otherObj.measurements.parameter === "pm25");
});
});
}
getAirQualityJson();
https://jsfiddle.net/7quL0asz/
The loop is running through I as you can see I tried [2] which was the original placement of the 'pm25' value but then it switched up it's spot to the 3rd or 4th spot, so it is unpredictable.
I tried jQuery Grep and Map but it came back undefined or false.
So my question is, how would I parse this to get the 'pm25' key,value. After that, I can get the rest if I need them.
Thank you in advance for all the help.
You can use array#find and optional chaining to do this,
because we are using optional chaining, undefined will be returned if a property is missing.
Demo:
let data = {"meta":{"name":"openaq-api","license":"CC BY 4.0d","website":"https://u50g7n0cbj.execute-api.us-east-1.amazonaws.com/","page":1,"limit":100,"found":1},"results":[{"location":"Metro Lofts","city":null,"country":"US","coordinates":{"latitude":39.731,"longitude":-104.9888},"measurements":[{"parameter":"pm10","value":49.9,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"pm1","value":24,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"um100","value":0,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um025","value":0.28,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um010","value":4.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"pm25","value":41.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"}]}]}
let found = data?.results?.[0]?.measurements?.find?.(
({ parameter }) => parameter === "pm25"
);
console.log(found);
You can iterate over measurements and find the object you need:
const data = '{"meta":{"name":"openaq-api","license":"CC BY 4.0d","website":"https://u50g7n0cbj.execute-api.us-east-1.amazonaws.com/","page":1,"limit":100,"found":1},"results":[{"location":"Metro Lofts","city":null,"country":"US","coordinates":{"latitude":39.731,"longitude":-104.9888},"measurements":[{"parameter":"pm10","value":49.9,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"pm1","value":24,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"},{"parameter":"um100","value":0,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um025","value":0.28,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"um010","value":4.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"particles/cm³"},{"parameter":"pm25","value":41.1,"lastUpdated":"2021-08-09T20:49:38+00:00","unit":"µg/m³"}]}]}';
const json = JSON.parse(data);
let value = null;
const measurements = json?.results?.[0]?.measurements ?? null;
if(measurements)
for (const item of measurements)
if (item.parameter === 'pm25') {
value = item.value;
break;
}
if (value) {
// here you can use the value
console.log(value);
}
else {
// here you should handle the case where 'pm25' is not found
}

How to get inner array in javascript

I'm trying to get all the contents from an array.
This is the function that extracts the data for display via innerHTML:
window.location.href = 'gonative://contacts/getAll?callback=contacts_callback';
function contacts_callback(obj) {
var contactinfo = obj.contacts.map(({givenName}) => givenName) + " " +
obj.contacts.map(({familyName}) => familyName) + " " + " (" +
obj.contacts.map(({organizationName}) => organizationName) + ") " +
obj.contacts.map(({phoneNumbers.phoneNumber}) => phoneNumbers.phoneNumber) + "<br>";
document.getElementById("demo").innerHTML = contactinfo;
}
This is an example of what the input looks like when there are only 2 contacts:
{"success":true,"contacts":[
{
"emailAddresses":[],
"phoneNumbers":
[
{
"label":"unknown",
"phoneNumber":"XXX-XXXXXXX"
}
],
"givenName":"John",
"organizationName":"Apple",
"familyName":"Appleseed",
},
{
"emailAddresses":[],
"phoneNumbers":
[
{
"label":"unknown",
"phoneNumber":"XXX-XXXXXXX"
}
],
"givenName":"John",
"organizationName":"Apple",
"familyName":"Appleseed",
},
]
}
I just want the result to be listed as:
John Appleseed (Apple) XXX-XXXXXXX
John Appleseed (Apple) XXX-XXXXXXX
Two issues:
You are displaying all given names, then all family names, ...etc, each with a separate .map() call. Instead only perform one .map() call on the array and then display the properties for each iterated object.
phoneNumbers.phoneNumber is not a correct reference. phoneNumbers is an array, so you should iterate it.
Also:
Template literals make it maybe a bit easier to build the string
You can use .join("<br>") to glue the lines together with line breaks.
Here is a corrected version:
function contacts_callback(obj) {
var contactinfo = obj.contacts.map(o =>
`${o.givenName} ${o.familyName} (${o.organizationName}) ${
o.phoneNumbers.map(n => n.phoneNumber)
}`)
.join("<br>");
document.getElementById("demo").innerHTML = contactinfo;
}
// Demo
var obj = {"success":true,"contacts":[{"emailAddresses":[],"phoneNumbers":[{"label":"unknown","phoneNumber":"XXX-XXXXXXX"}],"givenName":"John","organizationName":"Apple","familyName":"Appleseed",},{"emailAddresses":[],"phoneNumbers":[{"label":"unknown","phoneNumber":"XXX-XXXXXXX"}],"givenName":"John","organizationName":"Apple","familyName":"Appleseed",},]};
contacts_callback(obj);
<div id="demo"></div>
It is hard to give an answer since is hard to tell what you can have in your phoneNumbers array and if you will also display one line for each phone number in that array.
I'll do something like this:
function contacts_callback(obj) {
let arrayContacts = [];
// Iterate over all your contacts
obj.contacts.forEach(item => {
// Iterate over each contact's phone numbers
item.phoneNumbers.forEach(phone => {
// Building your string with string interpolation and pushing to result array
// You could also add <br> or other tags needed here
arrayContacts.push(`${item.givenName} ${item.familyName} (${item.organizationName}) ${phone.phoneNumber}`);
});
});
// Return your array, use it in your innerHTNL, etc.
return arrayContacts;
}
If Your obj is called "obj", than:
const result = obj.contacts.map(contact =>{
return `${contact.givenName} ${contact.familyName} (${contact.organizationName}) ${contact.phoneNumbers[0].phoneNumber}`
}
this code will give back an array of informations that U asked, but if user has more than 1 phone number, it will take only first from the list

Get a JSON Key based off of a user select

I am currently creating a tool that allows users to put in their state and category to see what the 3 price plans are. These 2 selections (state/category) will be picked via select field, and the data containing these numbers is in a JSON file:
[{
"Alabama/Category1/Price1":"$123,123 ",
"Alabama/Category1/Price2":"$123,123 ",
"Alabama/Category1/Price3":"$123,123 ",
"Alabama/Category2/Price1":"$345,345 ",
"Alabama/Category2/Price2":"$345,345 ",
"Alabama/Category2/Price3":"$345,345 ",
"Alabama/Category3/Price1":"$456,789 ",
"Alabama/Category3/Price2":"$456,789 ",
"Alabama/Category3/Price3":"$456,789 ",
"Alabama/Category4/Price1":"$321,321 ",
"Alabama/Category4/Price2":"$321,321 ",
"Alabama/Category4/Price3":"$321,321 ",
"Alaska/Category1/Price1":"$123,123 ",
"Alaska/Category1/Price2":"$123,123 ",
"Alaska/Category1/Price3":"$123,123 ",
"Alaska/Category2/Price1":"$345,345 ",
"Alaska/Category2/Price2":"$345,345 ",
"Alaska/Category2/Price3":"$345,345 ",
"Alaska/Category3/Price1":"$456,789 ",
"Alaska/Category3/Price2":"$456,789 ",
"Alaska/Category3/Price3":"$456,789 ",
"Alaska/Category4/Price1":"$321,321 ",
"Alaska/Category4/Price2":"$321,321 ",
"Alaska/Category4/Price3":"$321,321 ",
}]
Basically on button click, I would like to loop through the JSON file and get the State/Category based off the users selections. Being that there are some "/"'s in that key path, I tried stashing the users selection in a variable, so that I could target each price point and display them on the page. My way of trying that was stashing it in a variable like so:
var test = stateSelected + '/' + categorySelected + '/Price1';
This, however does not work, and was wondering if there was any additional insight as to how to achieve this? Reading some other material, it seems some are recommending to use $.parseJSON, but that was not working either. For that I used:
$.getJSON("json_data.json", function(obj) {
$.each($.parseJSON(data), function(key, value) {
//code here
});
});
Sorry for the longevity on this, but too many times on this site I have seen people not give enough information for people to be able to understand the real issue, and I hope I have outlined mine correctly. Any help on this would be appreciated. Thanks!
EDIT: Also, if you think there is a different way to present the JSON data other than the way I have it here, let me know. The data will be updated via spreadsheet and I used an Excel -> JSON translator tool and this was the way it spit back out the data.
I'd format the JSON in the following way:
var options = {
Alabama: {
Category1: {
Price1: "$123, 123",
Price2: "$123, 123",
}
}
}
and then:
var priceOptions = options[stateSelected][categorySelected];
If you cannot alter the JSON then you'll have to iterate through each key in the object:
function getPricePoints(state, category, onComplete)
{
$.getJSON("json_data.json", function(obj)
{
var result = {};
for(key in obj)
{
if(obj.hasOwnProperty(key) && key.indexOf(state + "/" + category + "/") == 0)
{
result[key] = obj[key];
}
}
onComplete(result);
});
}
If you can alter the way the JSON is represented then why not store the data like so:
var options = {
"Alabama/Category1" : {
"Price1":"$123,123 ",
"Price2":"$123,123 ",
"Price3":"$123,123 "
},
"Alabama/Category2" : {
"/Price1":"$345,345 ",
"Price2":"$345,345 ",
"Price3":"$345,345 "
}
...
}
Then you get slash the user's inputs and get all the prices options for that combination of state and category?
test = stateSelected + '/' + categorySelected;
var priceOptions = options[test];

Why am I unable to push these results to an array?

I'm trying to change
results = $("x", xmlResponse).map(function() {
to
results.push = $("x", xmlResponse).map(function() {
but doing so prevents any Autocomplete suggestions from appearing.
If I simply remove "push" again, the Autocomplete suggestions appear correctly with no issue.
How can I use results.push properly here?
Use .get() to return an array from .map()
results = $("Game", xmlResponse).map(function() {
return {
value: $("GameTitle", this).text()
+ ", "
+ ($.trim($("ReleaseDate", this).text()) || "(unknown date)")
};
}).get()
push is a method, not a property .
You can't use it as a property.
results.push = $("Game", xmlResponse).map(function() {
In order to push element into results , results have to be an array
Like this
var results =[];
results.push("your things");

Iteration Of JSON Array Of Objects Not Working

I have an array of objects that should be looking like this...
[{"Name":"blah","Description":"blah"},{"Name":"blah2","Description":"blah2"}]
Using Javascript/jQuery, how can I get the key/value pairs? I've tried many different ways but to no avail. When I try to get the length, it always returns the character count and iterates through each character and not the actual count of objects? When I run this, it returns an alert for [object Object], [object Object] spelled out by each character....
function DisplayItems(data) {
$.each(data, function () {
$.each(this, function (key, value) {
alert(value);
});
});
}
Now that I look at this, is it not the array of objects I'm expecting? How can I actually return the string so I can actually see what's really in it and maybe go from there?
**EDIT:
This is my function to get the orders (cut out the crap and showing you an alert)... I call jQuery.Ajax and pass the returned data to displayOrders(data). The orders have a composite property of Items containing a list of Item.
function displayOrders(data) {
$('#gdvOrders tbody').empty();
for (var key in data.d) {
alert(data.d[key].Items);
}
This is what I passed to displayItems, what you see in the alert function. I display the Orders in one table (hiding some columns including the Items), and want to display the Items for each order in another table when they select a row in the orders table. In the function shown above I can write...
data.d[key].OrderId
and it will display as normal. How do I display the properties for each item?
The jQuery.Ajax function is set to content-type: 'application/json; charset=utf-8' and this is where I get the orders from...
[WebMethod]
public static List<Order> GetOrdersByDept(Department department, Filter filter, DateTime? dateFrom = null, DateTime? dateTo = null)
{
return OrderLists.GetOrdersByDepartment((Department)department, (Filter)filter, dateFrom, dateTo);
}
See this is working:
data=[{"Name":"blah","Description":"blah"},{"Name":"blah2","Description":"blah2"}]
data.forEach(function(i,j){
console.log("Name :"+i.Name+" Description :"+i.Description);
})
Using JavaScript, simply use the for .. in loop
for(var i = 0; i < data.length; i++) {
var obj = data[i];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
alert(key + " = " + obj[key]);
}
}
}
Fiddle here - http://jsfiddle.net/XWsvz/
Now that I look at this, is it not the array of objects I'm expecting? How can I actually return the string so I can actually see what's really in it and maybe go from there?
If the object is being returned as a string, you can simply alert it. However, if your function is being passed an unknown object, you can always convert it back to a JSON string and alert it so that you can visualize the structure:
function displayItems(data) {
alert(JSON.stringify(data));
...
}
As a sidenote, I changed the first letter in your function to a lowercase letter to match naming conventions for functions in JavaScript.
Looks like you're close:
function DisplayItems(data) {
console.log('data is: ', JSON.stringify(data));
$.each(data, function (key, arrayElement, index) {
console.log('arrayElement ' + index + ' is: ', JSON.stringify(arrayElement));
$.each(arrayElement, function (key, value) {
console.log('key: ' + key + ' val: ' + value);
});
});
}
http://jsfiddle.net/ux9D8/
With your data this gives me the following output:
data is: [{"Name":"blah","Description":"blah"},{"Name":"blah2","Description":"blah2"}]
arrayElement undefined is: {"Name":"blah","Description":"blah"}
key: Name val: blah
key: Description val: blah
arrayElement undefined is: {"Name":"blah2","Description":"blah2"}
key: Name val: blah2
key: Description val: blah2

Categories