I have the following array with multiple arrays inside the object, how do I generate a query string, where the output should be.
Where services and accountTypes for example that are entries from array it becomes a key in query string.
The value in query string is the id from object in each array
Output should be for example
services=10&services=30&accountTypes=20
Array
[
{
"services": [
{
"id": "10",
"name": "PIX"
},
{
"id": "30",
"name": "Income"
},
],
"accountTypes": [
{
"id": "20",
"name": "Digital Account"
}
]
}
]
My function that I tried.
I tried it with the encodeURIComponent as below, but it's generating undefined
const params = initialFilterDataJson.map((param: QueryParamsType) => {
return encodeURIComponent(param.key) + '=' + encodeURIComponent(param.id)
})
const queryString = params.join('&')
http://localhost:3000/api/accounts?undefined=undefined
Your code is not nesting deep enough in the data structure. You need to have nested loops, first to visit the objects in the outer array, then to visit the keys (with corresponding arrays) of such an object, and then to visit each inner object in such an array:
const initialFilterDataJson = [{"services": [{"id": "10","name": "PIX"},{"id": "30","name": "Income"},],"accountTypes": [{"id": "20","name": "Digital Account"}]}];
const queryString = initialFilterDataJson.flatMap((param) =>
Object.entries(param).flatMap(([key, arr]) =>
arr.map(({id}) => encodeURIComponent(key) + '=' + encodeURIComponent(id))
)
).join('&');
console.log(queryString);
Side note: some web servers can deal better with duplicate keys in the query string when they are suffixed with [], like services[]=10&services[]=20.
Related
I have the following object below with multiple arrays.
{
"services": [
{
"id": "100",
"name": "PIX"
},
{
"id": "200",
"name": "Rendimentos"
}
],
"channels": [
{
"id": "300",
"name": "Chat"
}
]
}
The idea is to generate query strings, something like that.
services=100&services=200&channels=300
I know you can do it with map and join, but I would know if it was with a pure object, now this format below, I'm confused
You can use URLSearchParams() API.
Iterate your data and append key/value pairs or map an entries array to pass to the constructor
I have no idea what determines the expected output you have shown from the data displayed so am using a simpler data structure for demonstration purposes.
You can combine with URL() API to create full url string as shown below also
const data = [
{name:'foo', value:10},
{name:'bar', value:20}
]
// Loop and append key/values
const params = new URLSearchParams();
data.forEach(e => params.append(e.name, e.value));
console.log('params:', params.toString());
// Alternate approach passing entries array to constructor
const params2 = new URLSearchParams(data.map(e => [e.name,e.value]));
console.log('params2:',params2.toString())
//Adding to a URL
const url = new URL('http://example.com')
url.search = params
console.log('Full url:',url)
Using the updated array data in question:
const data={services:[{id:"100",name:"PIX"},{id:"200",name:"Rendimentos"}],channels:[{id:"300",name:"Chat"}]};
const entries = [];
Object.entries(data).forEach(([k,arr])=> arr.forEach(({id}) => entries.push([k,id])));
const params = new URLSearchParams(entries);
const url = new URL('http://example.com')
url.search = params;
console.log(url)
Looks like you're hung up on trying to iterate an object with map() or join(), which you can't do directly. Instead you can use Object.entries to convert the object into an array and iterate that. Since there is a nested map() you can flat() it before join()
let obj = {
"services": [{
"id": "100",
"name": "PIX"
},
{
"id": "200",
"name": "Rendimentos"
}
],
"channels": [{
"id": "300",
"name": "Chat"
}]
}
let queryString = Object.entries(obj).map(s => s[1].map(e => `${s[0]}=${e.id}`)).flat().join('&')
console.log(queryString)
I have one react native app the shows some ingredients and the user can select some of it to filter one specific recipe and see all the details, my doubt is, how can I convert the Array of ingredient objects to an Array of "names" and send it via Axios?
Array of objects I am receiving from the API:
Array [
Object {
"id": 8,
"isSelected": true,
"name": "leite condensado",
},
Object {
"id": 9,
"isSelected": true,
"name": "creme de leite",
},
]
and the API expect something like
/report?name='suco de limão', 'bolacha'
So, I need to extract only the values from the name Key, as Array.
Anyone knows if I can do it in the front to keep the API without any update?
You can use the Array.prototype.map() function. Array.prototype.map( ) MDN Documentation
What this does is basically for each element call a callback fn on your current array and returns a new array as per the code you write in the callback fn. What I've done in the below code is to just retrieve the 'name' property of each object from the original array and return those names as a new array.
Then loop over the names array and append to your api URL. I have done both these things in the below code snippet, you can try and run it to understand it better.
const arr = [
{
id: 8,
isSelected: true,
name: 'leite condensado',
},
{
id: 9,
isSelected: true,
name: 'creme de leite',
},
];
const nameArr = arr.map(obj => obj.name);
//logging names array to console
console.log(nameArr);
//appending names to your api url
let url = `/report?name=`;
nameArr.forEach((name, index, ar) => {
index === ar.length - 1 ? (url += ` '${name}'`) : (url += `
'${name}', `);
});
//logging updated API URL to console
console.log(url);
Not sure if I understood the question completely, but maybe you need something like this?
let params = []
const array = [
{
"id": 8,
"isSelected": true,
"name": "leite condensado",
},
{
"id": 9,
"isSelected": true,
"name": "creme de leite",
},
]
array.map(item => params.push(item.name))
console.log(params)
https://codepen.io/pen/?editors=0011
The result would be ["leite condensado", "creme de leite"]
basically, you create a new array, then you map the results you have and push the value you want into this new array and you send it to your api
You can convert the array to an array of names as this
const arr = [
{
"id": 8,
"isSelected": true,
"name": "leite condensado",
},
{
"id": 9,
"isSelected": true,
"name": "creme de leite",
},
]
const names = arr.map(obj => {
return obj.name
})
console.log (names)
I have the same problem as up,I want to convert the Array of post objects received from jsonplaceholder by Axios to an Array of "post ids" and send it by array data to the reducer.js. After follow up solution, I get the correct answer as below.
axios.get('http://jsonplaceholder.typicode.com/posts?_start=10&_limit=5')
.then((res)=>{
const data=res.data
const ids = data.map(obj=>{
return obj.id
console.log('axios success:'+ids)
})
Console output as below:
axios success:11,12,13,14,15
I am trying to filter a JavaScript array (JSON array) with the string array, and set it back in itself.
I am using this code (Removed JSON.stringiFy from allRecords,it was just to show the records on console)
var statusFilters = component.get("v.statusFilters");
console.log('statusFilters--->'+statusFilters);
var allRecords = component.get("v.empWrapperList");
console.log('allRecords--->'+allRecords);
var filteredRecords = allRecords.filter(rec => rec.Status__c == statusFilters);
console.log(filteredRecords);
component.set("v.empWrapperList",filteredRecords);`
Here statusFilter is a string array and allRecords is an object array.
Here are the logs from console.
statusFilters--->Paid
ClaimsDemo.js:119 allRecords--->
[
{
"Id": "a1V2x000001K29pEAC",
"Name": "CL-0000004",
"Member__c": "0032x000004bgAkAAI",
"Date_of_Service__c": "2020-06-25",
"Provider__c": "a112x000003VXGEAA4",
"Status__c": "Void"
},
{
"Id": "a1V2x000001K14OEAS",
"Name": "CL-0000003",
"Member__c": "0032x000004bgAkAAI",
"Billed__c": 22,
"Date_of_Service__c": "2015-09-15",
"Provider__c": "a112x000003VXGEAA4",
"Status__c": "Denied"
},
{
"Id": "a1V2x000001K14JEAS",
"Name": "CL-0000002",
"Member__c": "0032x000004bgAkAAI",
"Billed__c": 22,
"Date_of_Service__c": "2019-10-16",
"Provider__c": "a112x000003VXGEAA4",
"Status__c": "Rejected"
},
{
"Id": "a1V2x000001K14EEAS",
"Name": "CL-0000001",
"Member__c": "0032x000004bgAkAAI",
"Billed__c": 22,
"Date_of_Service__c": "2020-06-04",
"Provider__c": "a112x000003VXGEAA4",
"Status__c": "Paid"
}
]
Actually it is unable to execute this line
var filteredRecords = allRecords.filter(rec => rec.Status__c == statusFilters);
Can you please help.
your first problem is stringifying.filter method is for array.
second problem is that you cant say rec.Status__c === statusFilters statusFiltersis array and Status__c is string. map to array your object array with correct key name and search rec.Status__c in this array. indexOf is a method to find in array
if statusFilters is just array which includes types like
["Void","Denied"]
then
var filteredRecords = allRecords.filter(rec => statusFilters.indexOf(rec.Status__c)>-1);
if statusFilters is an object array like
[ {"Status__c": "Void" }];
then
var filteredRecords = allRecords.filter(rec => ( statusFilters.map(x=>x.Status__c)).indexOf(rec.Status__c)>-1);
This question already has answers here:
Encode URL in JavaScript
(22 answers)
Closed 3 years ago.
How to append comma seperated values to url as search params using history.pushsate. with use of , RFC 3986, specifies that URI path components should not contain unencoded reserved characters and comma is one of those reserved characters. https://www.rfc-editor.org/rfc/rfc3986.
#code
window.history.pushState('new', 'inventory', '/new');
#Desired result
https://www.test.com/new?Year=2020,2019&Pricerange=10001-20000,20001-30000,30001-40000&Mileagerange=1001-2000,2001-3000&Bodystyle=4dr%20Car,Convertible
#Data i wanted to append
{
"year": [
"2017",
"2018"
],
"model": [
"Escape",
"Edge"
],
"mileage": [
"1-1000"
],
"bodyStyle": [
"Convertible",
"4dr Car",
"2dr Car"
],
"priceRange": [
"$20,000-$30,000",
"$30,000-$40,000"
]
}
jQuery.param() seems to repeat array values, so you'll have to find some existing library or write custom function.
Something like that (but maybe optimized a bit more):
/**
* Prepare `search` part of URL.
* #param {object} o Each key is a param name and value is an array of values
* #return {string}
*/
function createURLQuery (o) {
return Object.keys(o)
.map(key => `${encodeURIComponent(key)}=`
+ o[key].map(v => encodeURIComponent(v)).join(','))
.join('&')
}
// Example code
const data = {
"year": [
"2017",
"2018"
],
"model": [
"Escape",
"Edge"
],
"mileage": [
"1-1000"
],
"bodyStyle": [
"Convertible",
"4dr Car",
"2dr Car"
],
"priceRange": [
"$20,000-$30,000",
"$30,000-$40,000"
]
};
const newURL = `/new?${createURLQuery(data)}`;
console.log('Pushing new URL', newURL);
// window.history.pushState('new', 'inventory', newURL);
You'll have to implement any additional changes to data yourself. "Desired result" seems to drop "$" characters and capitalize parameter names.
Parse the JSON data to a JS object and parse the keys and values according to your needs. I don't think there's any way to achieve exactly the string format that you want, unless someone wrote a npm package for exactly this case (not deeply nested json object to a query string).
Make use of JSON.parse() and Object.entries() to build a query string based on the JSON input.
I've made an example to have a look at. You still need some parsing for currency and maybe something more.
See below if REPL link wouldn't work.
const json = `
{
"year": [
"2017",
"2018"
],
"model": [
"Escape",
"Edge"
],
"mileage": [
"1-1000"
],
"bodyStyle": [
"Convertible",
"4dr Car",
"2dr Car"
],
"priceRange": [
"$20,000-$30,000",
"$30,000-$40,000"
]
}`;
const parsedJson = JSON.parse(json);
let queryString = '?';
Object.entries(parsedJson).forEach(([key, value], index) => {
let string = `${index != 0 ? '&' : ''}${key}=${value.join()}`;
queryString += string;
});
const encodedQueryString = encodeURIComponent(queryString.trim())
I want to fetch all the names and label from JSON without loop. Is there a way to fetch with any filter method?
"sections": [
{
"id": "62ee1779",
"name": "Drinks",
"items": [
{
"id": "1902b625",
"name": "Cold Brew",
"optionSets": [
{
"id": "45f2a845-c83b-49c2-90ae-a227dfb7c513",
"label": "Choose a size",
},
{
"id": "af171c34-4ca8-4374-82bf-a418396e375c",
"label": "Additional Toppings",
},
],
},
]
}
When you say "without loops" I take it as without For Loops. because any kind of traversal of arrays, let alone nested traversal, involve iterating.
You can use the reduce method to have it done for you internally and give you the format you need.
Try this :
const data = {
sections: [
{
id: "62ee1779",
name: "Drinks",
items: [
{
id: "1902b625",
name: "Cold Brew",
optionSets: [
{
id: "45f2a845-c83b-49c2-90ae-a227dfb7c513",
label: "Choose a size"
},
{
id: "af171c34-4ca8-4374-82bf-a418396e375c",
label: "Additional Toppings"
}
]
}
]
}
]
};
x = data.sections.reduce((acc, ele) => {
acc.push(ele.name);
otherName = ele.items.reduce((acc2, elem2) => {
acc2.push(elem2.name);
label = elem2.optionSets.reduce((acc3, elem3) => {
acc3.push(elem3.label);
return acc3;
}, []);
return acc2.concat(label);
}, []);
return acc.concat(otherName);
}, []);
console.log(x);
Go ahead and press run snippet to see if this matches your desired output.
For More on info reduce method
In the context of cJSON
yes, we can fetch the key value for any of the object.
1 - each key value is pointed by one of the objects. will simply fetch that object and from there will get the key value.
In the above case for
pre-requisition: root must contain the json format and root must be the cJSON pointer. if not we can define it and use cJSON_Parse() to parse the json.
1st name object is "sections" will use
cJSON *test = cJSON_GetObjectItem(root, "sections");
char *name1 = cJSON_GetObjectItem(test, "name" )->valuestring;
2nd name key value
cJSON *test2 = cJSON_GetObjectItem(test, "items");
char *name2 = cJSON_GetObjectItem(tes2, "name")->valuestring;
likewise, we can do for others as well to fetch the key value.