Node js defining response payload structure - javascript

I am having a data coming from elastic search with hits object through node server . I want to send back to the user by transforming it into a payload structure object . For example ,
{
"title":"test",
"count":36
"description":"something for test"
},
{...}
]```
Then from this array I want only title to be sent to user . How can I transform in node js as an object by defining a model
Transform Structure :
```{ "pageNo":1,
"payload":
[
{"title":"test"}
,{...},
{...}
] }```

You are dealing with array so you need to iterate over it. Best approach in that case is to use map method:
const array = [
{
"title":"test",
"count":36,
"description":"something for test",
},
];
const responseItems = array.map(item => {
return { title: item.title };
});
const response = {
payload: responseItems,
// other fields...
};

Related

Access and extract values from doubly nested array of objects in JavaScript

I have an array of objects and within those objects is another object which contains a particular property which I want to get the value from and store in a separate array.
How do I access and store the value from the name property from the data structure below:
pokemon:Object
abilities:Array[2]
0:Object
ability:Object
name:"blaze"
1:Object
ability:Object
name:"solar-power"
How would I return and display the values in the name property as a nice string like
blaze, solar-power ?
I tried doing something like this but I still get an array and I don't want to do a 3rd loop since that is not performant.
let pokemonAbilities = [];
let test = pokemon.abilities.map((poke) =>
Object.fromEntries(
Object.entries(poke).map(([a, b]) => [a, Object.values(b)[0]])
)
);
test.map((t) => pokemonAbilities.push(t.ability));
Sample Data:
"pokemon": {
"abilities": [
{
"ability": {
"name": "friend-guard",
"url": "https://pokeapi.co/api/v2/ability/132/"
},
"ability": {
"name": "Solar-flare",
"url": "https://pokeapi.co/api/v2/ability/132/"
}
}
]
}
Then I am doing a join on the returned array from above to get a formatted string.
It just seems like the multiple map() loops can be optimized but I am unsure how to make it more efficient.
Thank you.
There is no need for a loop within loop. Try this:
const pokemon = {
abilities: [{
ability: {
name: 'friend-guard',
url: 'https://pokeapi.co/api/v2/ability/132/'
},
}, {
ability: {
name: 'Solar-flare',
url: 'https://pokeapi.co/api/v2/ability/132/'
}
}]
};
const pokemonAbilities = pokemon.abilities.map(item => item.ability.name).join(', ');
console.log(pokemonAbilities);

From single array convert to an array of object with keys coming from a JSON response -JAVASCRIPT-

I am receiving a json response from an API call. I need to store its keys, and create an array of an object. I am intending to this array of an object is created dynamically no matter the keys of the response.
I've already got the keys like this:
const json_getAllKeys = data => {
const keys = data.reduce((keys, obj) => (
keys.concat(Object.keys(obj).filter(key => (
keys.indexOf(key) === -1))
)
), [])
return keys
}
That returned an array (using a sample json):
['name','username', 'email']
But I am trying to use that array to create an array of object that looks like this one
[
{
name: "name",
username: "username",
email: "Email",
}
];
I've been trying mapping the array, but got multiple objects because of the loop, and I need a single one to make it work.
keys.map(i=>({i:i}))
[
{ i: 'id' },
{ i: 'name' },
{ i: 'username' },
{ i: 'email' }
]
Any hint would be useful!
Thanks in advance :D
What you're looking for is Object.fromEntries, which is ECMA2019, I believe, so available in Node >=14 and will be provided as a polyfill if you employ babel.
I can't quite discern what your reduce should produce, but given the sample input, I would write
const input = ['name','username', 'email'];
const result = Object.fromEntries(input.map(name => ([name, name])));
// result == { name: 'name', username: 'username', email: 'email' }
You're definitely on the right track. One thing to remember is the map function will return the SAME number of output as input. So in your example, an array of 3 returns an array of 3 items.
For this reason, map alone is not going to give you what you want. You may be able to map => reduce it. However, here is a way using forEach instead. This isn't a strictly functional programming style solution, but is pretty straight forward and depending on use case, probably good enough.
let keys = ['name','username', 'email'] //you have this array
const obj = {}; // empty object to hold result
keys.forEach(i => {
obj[i] = i; // set the object as you want
})
console.log(obj); // log out the mutated object
// { name: 'name', username: 'username', email: 'email' }

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

can't address JSON object

I have a locally saved JSON file in which I have a bunch of objects/strings. I have trouble addressing each value. The beginning looks like this:
{
"result":{
"heroes":[
{
"name":"npc_dota_hero_antimage",
"id":1,
"localized_name":"Anti-Mage"
},
{
"name":"npc_dota_hero_axe",
"id":2,
"localized_name":"Axe"
},
...
after including it in my JS I attempt to console log console.log(heroes.result[0].heroes[0].name).
I know it's a dumb question but I can't figure it out right now.This is my markup:
const endpoint = './heroes.json'
let heroes = []
fetch(endpoint)
.then(blob => blob.json())
.then(data => heroes.push(data))
console.log(heroes)
Result is an object and not an array. You need to remove the index from that
heroes.result.heroes[0].name
var heroes={
"result":{
"heroes":[
{
"name":"npc_dota_hero_antimage",
"id":1,
"localized_name":"Anti-Mage"
},
{
"name":"npc_dota_hero_axe",
"id":2,
"localized_name":"Axe"
}]
}
}
console.log(heroes.result.heroes[0].name)
You need to use . for object properties as result is object you need to use . instead of []
var heroes={
"result":{
"heroes":[
{
"name":"npc_dota_hero_antimage",
"id":1,
"localized_name":"Anti-Mage"
},
{
"name":"npc_dota_hero_axe",
"id":2,
"localized_name":"Axe"
}]
}
}
console.log(heroes.result.heroes[0].name)
`heroes.result.heroes[0].name`
That should do. Bear in mind that result is a property of the first object 'heroes' as well as the second 'heroes' is a property of the object 'result'.
The key of the second 'heroes', however, is an array. Therefore you use an index to access the first element in the array: heroes[0].
Third, heroes[0] contains an object so we are accessing its property 'name', therefore .name.

Extract data from API Object in React

I'm trying to retrieve data from an API with the following JSON output and I have a function in react that I call.
I can see the api output in console.log(users) so the data is being passed into the function.
I am trying to output the array contained in "data" but can't seem to access the data.
{
"dataCount": 2,
"data": [
{
"name": "Test review header",
"text": "This is adescription for a test review",
"img": "http://pngimg.com/upload/pigeon_PNG3423.png"
},
{
"name": "Test review header2",
"text": "This is adescription for a test review2",
"img": "http://pngimg.com/upload/pigeon_PNG3422.png"
}
]
}
renderUsers() {
const { users } = this.props;
console.log(users);
Object.keys(users).map(name => users[name])
console.log(users[name]);
};
The data you need to iterate over is present in the data field of users.
When you are using lists you have to specify the key property, to make react keep track of each item in list.
renderUsers() {
const { users } = this.props;
return (
<ul>
{
users.data.map(name => {
<li key={name}>users[name]</li>
})
}
</ul>
)
}
First of all, I don't use react but what you want should be the same in other javascript frameworks.
Are you sure that it is JSON you receive?
We need to be sure that you receive a JSON object and not normal text. Lets say you have a function parseResponse(data). We can call JSON.parse(data) to parse the data param to a json object. It is also possible that you store the result in a variable.
Using the JSON object
When we are sure you have the param parsed to a JSON object, we get it's data. For example, if you want to get the name of the first object in data, you can call:
parsedJson.data[0].name
where parsedJson is the result of JSON.parse(data),
data is an array of objects in the JSON,
0 is the first object in the array
It is possible that you have this kind of function then:
function parseResponse(data) {
var parsedJson = JSON.parse(data);
for(var i = 0; i < parsedJson.data.length; i++) {
console.log(parsedJson.data[i].name);
}
}
see jsfiddle

Categories

Resources