how to iterate over two responses one after another using javascript - javascript

I am initialized one variable with two responses from two async calls like this below.
const items = await service.fetchDropdownFieldItems(payload.url);
It is storing the responses one after another and it is working fine. Those responses are like below:
1st response : [{id:1, value:'Shoe'},{id:2,value:'Boutique'},{id:3,value:'Clothing'}]
2nd response: {data:[{country_id:1, country_name:'Australia'},{country_id:2,country_name:'France'},{country_id:3,country_name:'USA'}]}
Now, i want to format 2nd response's data array and replace the 2nd response with my formatted response.
Now, if i check items variable it should contain like this
1st response : [{id:1, value:'Shoe'},{id:2,value:'Boutique'},{id:3,value:'Clothing'}]
2nd response: [{id:1, value:'Australia'},{id:2, value:'France'},{id:3, value:'USA'}]}
Any approach for doing like this. There is no issue on async call or url etc. Only i want to change the response and replace with old one.

const formattedResponse = response.data.map((entry)=>({
id: entry.country_id,
value: entry.country_name
} ) )
you might place this logic somewhere inside service.fetchDropdownFieldItems, so you don't need to manually change your data everytime you fetch the items
Edit
Here is an example of how to use it inside a fetching function. You can change fetch with axios if you prefer
const formatResponse=(data)=>{
return data.map((entry)=>({
id: entry.country_id,
value: entry.country_name
} ) )
}
const fetchDropdownFieldItems =(url, options={})=>{
return fetch(url, options)
.then(res=> res.json())
.then(res=>res.data)
.then(formatResponse) //shorthand for .then(data=> formatResponse(data)
}
Use it as follows:
fetchDropdownFieldItems(...).then(doSomething)
//same as
fetchDropdownFieldItems(...).then(formattedData => doSomething(formattedData))

[].map should do the trick
const res2 = {
data: [{
country_id: 1,
country_name: 'Australia'
}, {
country_id: 2,
country_name: 'France'
}, {
country_id: 3,
country_name: 'USA'
}]
}
const result2 = res2.data.map(v => ({
id: v.country_id,
value: v.country_name
}))
console.log(result2)

const processData = (response) => {
const dataArray = [];
response.data.forEach(({country_id,country_name})=>{
dataArray.push({ id: country_id, value: country_name });
})
return dataArray;
}
This answer is the same as previous one but, takes less time to execute, and a little bit optimized
or also be used as
const processData = (response) => {
return response.data.map(({country_id,country_name})=>({ id: country_id, value: country_name }))
}

Related

How to parse json if Key'name dynamicly changes each time node js

I receive JSON data from the service, but the keys change in the data with each request, below I will give an example in three versions.
Exmaple 1:
{
"trackingPayloads": {
"Rltyn4gLRIWRKj9kS0YpWXytG81GZwcPWjEE7f31ALlq": "{"title":"Red Shoes","index":3,"id":"17777","type":"category"}',
"ywtA6OyM0hzVZZvnUjxoxJDI1Er9ArfNr8XKyi1D5Zzk": "{"title":"White Shoes","index":3,"id":"17777","type":"category"}',
}
}
Example 2:
{
"trackingPayloads": {
"36tW7DqZ3H9KKBEAumZmowmUwmDRmVCjQgv5zi9GM3Kz": "{"title":"Red Shoes","index":3,"id":"17777","type":"category"}',
"OgtE51n3YtvrVXWLFjPmpnRt2k5DExF7ovxmBTZrZ6wV": "{"title":"White Shoes","index":3,"id":"17777","type":"category"}',
}
}
Example 3:
{
"trackingPayloads": {
"k2toY29glt2JEp9Wi1X5M7ocno0E0mS4JQVyDuGyQ2rM": "{"title":"Red Shoes","index":3,"id":"17777","type":"category"}'",
"5ef2ec3c3573eebecc9690b69619ec7b9c93b609": "{"title":"White Shoes","index":3,"id":"17777","type":"category"}',
}
}
As you can see, the data included in the keys does not change since I am requesting the same information, but the key will change with each request.
Please help, what are the options to get the data Title, Index and any other content in these keys using node js?
Only one option came to my mind - to rename the keys upon receipt in 1,2,3 ... and then get data from them, but this needs to be done dynamically, since about 120 requests per minute are made, you need to get this data quickly, there are no options to save it to a file (I didn’t understand how)
UPDATE, added my code.
I am attaching an example of my code, the idea is to eventually get the data I need from the right keys from trackingPayloads, please help with the code <3
const AwaitAPIResponse = await ProductAPI(product_sku);
const $ = cheerio.load(AwaitAPIResponse);
const JSONDATA = [];
$('pre').each(function() {
JSONDATA.push($(this).text());
});
const ProductJson = JSON.parse(JSONDATA[0]) // this is where I get all the data
const MainJson = ProductJson["trackingPayloads"] // here I go to the trackingPayloads you saw above
How can I get the data I need?
You can use Object.keys() to get all the different keys of an object and use a loop to go through them.
Therefore, you can rework this code in such a way that each of the values is stored as an element in an array, maybe makes the data easier to work with:
const convert = object => {
const ret = []
for (const key of Object.keys(object)) {
ret.push(object[key])
}
return ret
}
This will give you following result for your use case:
[{"title":"Red Shoes","index":3,"id":"17777","type":"category"},
{"title":"Red Shoes","index":3,"id":"17777","type":"category"}]
The way you'd call this is as follows:
const some_parsed_json = {
"k2toY29glt2JEp9Wi1X5M7ocno0E0mS4JQVyDuGyQ2rM": {
title:"Red Shoes",
index:3,
id:"17777",
type:"category"
},
"5ef2ec3c3573eebecc9690b69619ec7b9c93b609": {
title:"Red Shoes",
index:3,
id:"17777",
type:"category"
}
}
const json_object_values = convertor(some_parsed_json)
If you don't car about the key you could use Object.values on the received object to get the values
Object.values(payload)
// With your example it will return:
// [{"title":"Red Shoes","index":3,"id":"17777","type":"category"},
// {"title":"Red Shoes","index":3,"id":"17777","type":"category"}]
or in a more complete example
async function getParsedValues() {
const responseString = await service.getData(); // '{"trackingPayloads":{"Rltyn4gLRIWRKj9kS0YpWXytG81GZwcPWjEE7f31ALlq":{"title":"Red Shoes","index":3,"id":"17777","type":"category"},"ywtA6OyM0hzVZZvnUjxoxJDI1Er9ArfNr8XKyi1D5Zzk":{"title":"White Shoes","index":3,"id":"17777","type":"category"}}}'
const parsedResponse = JSON.parse(responseString); // { trackingPayloads: { Rltyn4gLRIWRKj9kS0YpWXytG81GZwcPWjEE7f31ALlq: { title:'RedShoes', index: 3, id: '17777', type: 'category' }, ywtA6OyM0hzVZZvnUjxoxJDI1Er9ArfNr8XKyi1D5Zzk:{title:'WhiteShoes', index: 3, id: '17777', type: 'category' } }}
const values = Object.values(parsedResponse); // [{"title":"Red Shoes","index":3,"id":"17777","type":"category"}, {title:'WhiteShoes', index: 3, id: '17777', type: 'category' }]
return values;
}

How to replace a object inside JSON array with a fetch

I have a JSON that looks like this:
[{
is_email_opt_in: false,
credit_card_type: 'visa',
order_source: 'www',
channel_id: 1,
external_source: '',
products: {
url: 'https://api.bigcommerce.com/stores/XXX/v2/orders/149/products',
resource: '/orders/149/products'
}
}]
I'm trying to replace all "products" fields with the a fetch result that comes from BigCommerce API based on the value of the products.resource key.
This is my current code:
result = await this.instanceV2.get(`/orders`);
if (result)
result.forEach(
async (order) =>
(order.products = await this.instanceV2.get(
order.products.resource
))
);
But it's not working, the field doesn't get replaced.

how to convert an array to a array of objects with additional information in react using map when doing a POST api request

I'm new with react and I'm stuck at a problem, kindly help me.
array looks like this:
surveyors=[jj,kk]
The length of array can be variable i.e.there can be more values.
what i want to send in post api is:
data:[
{
name:"kk",
is_active:True,
company:26
},
{
name: "jj",
is_active:True,
company:26
}
]
I'm using postapi like this:
const postURL = moduleURL("url");
requests({
method: "post",
url: postURL,
data: [
{
name:"kk",
is_active:True,
company:26
},
{
name: "jj",
is_active:True,
company:26
}
],
})
.then((response) => {
console.log(response);
})
.catch((err) => console.log(err));
}
if there was a fixed data i could do it but since the data in array surveyor is variable i cannot fix it.
note- company here is the company id that i have stored in a variable and it will be same for every object in array and is_active will always be true.
var supervisor=["jj","kk"];
var result = supervisor.map(s => {return {name: s, is_active:true, company:26} });
console.log(result)
use map to create a new array of objects with extra attributes;
const supervisors = ["jj", "kk"];
const modifiedSupervisors = supervisors.map(item => ({name: item, is_active:true, company:26}));
now you can use this data in api call data: modifiedSupervisors,

Create an object or associative array with elements of an existing array and the result of a callout for each element

This is in the context of a node express route. I receive a get request with a query param that is a list of IDs. Now I need to make a call-out for each ID and store the result of the callout in an array or object. Each element of the first array (containing the IDs) need to be mapped to its corresponding result from the call-out. I don't have a way to modify the endpoint that I'm hitting from this route so I have to make single calls for each ID. I've done some research and so far I have a mixture of code and sudo code like this:
const ids = req.query.ids;
const idMembers = Promise.all(ids.map(async id => {
// here I'd like to create a single object or associative array
[ id: await callout(id); ]
}));
When all promises resolved I need the final result of idMembers to be like: (The response will be an object with nested arrays and objects I've just simplified it for this post but I need to grab that from the res.payload)
{
'211405': { name: 'name1', email: 'email1#test.co' },
'441120': { name: 'name2', email: 'email2#test.co' },
'105020': { name: 'name3', email: 'email4#test.co' }
}
Oh and of course I need to handle the callout and the promise failures and that's when my lack of experience with javascript becomes a real issue. I appreciate your help in advance!!
Some extra thought I'm having is that I'd have to map the results of the resolved promises to their id and then in a separate iteration I can then create my final array/object that maps the ids to the actual payloads that contain the object. This is still not answering any of my questions though. I'm just trying to provide as much information as I've gathered and thought of.
Promise.all returns an array of results (one item per each promise).
Having this temporary structure it is possible to build the needed object.
const arrayOfMembers = Promise.all(ids.map(async id => {
// ...
return { id, value: await callout(id) } // short syntax for { id: id, value: ... } (see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer)
}));
// arrayOfMembers = [
// { id: 211405, value: { name: 'name1', email: 'email1#test.co' } },
// ...
// ]
In pure JS it can be done with for loop or .forEach() call to iterate:
const res = {};
arrayOfMembers.forEach(el => {
const { id, value } = el;
res[el] = value;
});
or by using a single reduce() call
const res = arrayOfMembers.reduce((accumulator, el) => {
const { id, value } = el;
return { ...accumulator, [id]: value };
}, {});
in both cases res will be:
// res = {
// '211405': { name: 'name1', email: 'email1#test.co' },
// ...
// }
P.S.
There is a handy library called lodash. It has tons of small methods for data manipulation.
For example, _.fromPairs() can build an object from [[key1, value1], [key2, value2]] pairs.
As you mentioned you have lodash, so I think the following should work:
const arrayOfKeyValuePairs = Promise.all(ids.map(async id => {
// ...
return [ id, await callout(id) ] // array here so it matches what fromPairs needs
}));
const res = _.fromPairs(arrayOfKeyValuePairs);

fetch gives me a full array but it is empty when i try to access it

I get an object from a Symfony rest API. This object has a property "shooting" which is an array and this array is full when I console.log it but when i try to access it, it is empty
This is my fetch request
const getProjectsAvailable = async () => {
const data = await fetch(
`${process.env.GATSBY_CORE_URI}/api/dashboard/supplier/projects/available`,
{
headers: {
[`X-Auth-Token`]: `${token}`,
[`Accept`]: `application/json`,
},
}
);
return data;
};
Here is the project object that i get back from fetch request
0: {id: 258, name: "Project26-1", reference: "A6568", isOfferValidated: null, source: "dashboard", …}
It has a shooting key which contains an array and it is not empty
shootings: Array(1)
0:
addressCity: "Paris"
addressCountry: {id: 76}
But when i set this object to my component state, all values stay the same except the shooting key which becomes an empty array
const [projects, setProjects] = useState([]);
useEffect(() => {
getProjectsAvailable().then(res =>
res.json().then(data => {
setProjects(data);
})
);
}, []);
I have no idea why does it act like that.
Thanks in advance
EDIT :
For example, the first line with console.log gives me the response object with a full shooting array while the second one sets it to my state but shooting array is empty
useEffect(() => {
getProjectsAvailable().then(response => console.log(response));
getProjectsAvailable().then(response => setProjects(response));
}, []);
Ok it is my bad. Somewhere else in the code, there was a .split() on the shooting property which mutates the array so the props changed and shooting array got empty

Categories

Resources