React axios get data from JSON by object unique name - javascript

I have a structure like this:
{
"RESTAPI": {
"uniqueId": {
"id": "1",
"data_2": "data_2",
"data_3": true,
"mg_gateway": "Another Object"
},
"uniqueId2": {
"id": "1",
"data_2": "data_2",
"data_3": true,
"mg_gateway": "Another Object"
}
}
}
uniqueId can be with letters and numbers. I try to get it:
componentDidMount() {
axios.get('https:LINKNAME/RESTAPI.json')
.then(res => {
const fetched = res.data;
this.setState({ data: fetched });
})
}
And show in JSX:
{Object.keys(this.state.data).map((obj, i) => {
return <p key={i}>{obj}</p>
})}
In browser I can see only strings (typeof string): uniqueId and uniqueId2
But in console log I get all Objects.
console.log
But I cant show data inside each nested Object in map. So I try to use obj.data_2 and got undefined.
I thought that I can create new obj.map inside, but obj always string so it's impossible. Please, help me

You could use Object.values instead of Object.keys, then obj will be:
{
"id": "1",
"data_2": "data_2",
"data_3": true,
"mg_gateway": "Another Object"
}
or you can do this.state.data[key] as in previous replies
{Object.keys(this.state.data).map((key, i) => {
return <p key={i}>{this.state.data[key]}</p>
})}

Object.keys gives you only keys of object that is why you are only seeing the keys(uniqueId,uniqueId2)
So if you want whole data along with uniqueId do
this.state.data.map(...your code);
But I suspect you might get something like [object] so use
JSON.stringify in map function.
Or you can simply replace
<p key={i}> {this.state.data[obj]}</p>

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

How to destructure my api data in reactjs?

I am trying to destructure my array of objects with .map ? I have tried a few things but keep getting stuck. I am able to access single data by using the index but struggling with how to do it for them all.
I know it's something like this
const {name} = product;
and
const {attributes:name} = product;
but they don't work, they print "undefined".
Also tried this -
console.log(product.map(({name}) => (console.log(name))))
This is the data
console.log(product);
{
"attributes": {
"image": {
"data": []
},
"name": "test",
"description": "test product",
"price": 20,
"quantity": 0
}
}
This is what I want to achieve
<div className='grid grid-cols-4'>
{product.map(({attributes: name})=> (
<p>{name}</p>
))}
</div>
It's possible to destructer nested object.
Try something like this:
product.map(({attributes:{name}})=> ...
since it's Object this will work
const { name } = product.attributes;
or
<p>{product.attributes.name}</p>

Vue method to return all properties belonging to a single user returning [object Object]

Below is a dropdown which should ideally display a list of all tables belonging to a particular user.
<v-select
:items="allTables"
:item-text="tableNames"
return-object
/>
This is the structure of allTables. There could be more or less depending on the user:
[
{
"id": 3,
"name": "TABLE"
},
{
"id": 4,
"name": "KOP"
}
]
This is the method which displays tableNames:
tableNames() {
this.allTables.forEach(el => {
return element.map(a=>a.name)
});
},
Originally it was like this (however it led to the error I've listed in one of the answers):
tableNames: item => item.name;
Console logging
console.log(el.map(a=>a.name))
within the method above returns an array like below ('TABLE' is the name of a table and 'KOP' is the name of another table).
It's not returning any errors but the options for the v-select return [object Object]. I'm not sure what I'm doing wrong, can I ask why it's returning this?
The function to get all tables:
public function retrieveAllTables()
{
return Auth::user()->client->tables()->get();
}
Data variable:
data: () => ({
allTables: []
}),
API request:
getAllTables() {
apiClientGet(
routes["pages.retrieveAllTables"],
null,
response => {
this.allTables.push(response.data.flat());
// console logging this.allTables shows the structure above
}
);
},
The problem was that the api request wan't actually pushing the responses to allTables.
getAllTables() {
apiClientGet(
routes["pages.retrieveAllTables"],
null,
response => {
this.allTables = response.data;
return this.allTables;
}
);
},
I figured it out because console logging allTables in beforeMount returned an empty array when it should not have

Find nested object that contains a value

I have an object containing multiple other objects, inside these nested objects is an array containing multiple objects, each with a uid. I'm trying to loop over the objects and find the object that contains a particular uid.
My data looks like this
const data = {
"3c5671fde44f44f9ad59d59eb810d87e": {
"heading": "Heading 1",
"items": [
{
"content": {
"uid": "4fcd5f4af7a448d48463d4e0a11297d9"
}
},
{
"content": {
"uid": "31f975440a0a431592e127b2891cd142"
}
}
]
},
"ea80e8315b554c9bb40958a6cacf4b0c": {
"heading": "Heading 2",
"items": [
{
"content": {
"uid": "d6de8db4c2a74da6915a44d3964277d6"
}
}
]
}
}
The uid I want to search for is d6de8db4c2a74da6915a44d3964277d6 when found I want to return it's parent object so I can access the heading property.
Current code looks like this but it doesn't work, it's been a long day so I'm likely missing something really simple.
const currentUid = "d6de8db4c2a74da6915a44d3964277d6";
const currentHeading = Object.keys(data).forEach(section => {
return data[section].items.filter(item => {
return item.content.uid === currentUid;
});
});
When debugging it successfully evaluates to true when it finds the correct uid, it just doesn't return anything.
Any help welcome!
forEach is meant just for looping the array, use find to find the key of your object from Object.keys(data). And inside the callback use some instead of filter to check the existance. This solution will result in either the key of the object or null. To get the object, just check that a key is returned and then use that key to get the object:
const currentHeadingKey = Object.keys(data).find(section => {
return data[section].items.some(item => {
return item.content.uid === currentUid;
});
});
const currentHeading = currentHeadingKey != null ? data[currentHeadingKey] : null;
currentHeading is now either the whole object if found, null otherwise. You can access the heading property of that object.
Note: Since the callbacks of both find and some have only one statement in them, you can use the implicit return of arrow function to shorten the code:
const currentHeadingKey = Object.keys(data).find(section =>
data[section].items.some(item => item.content.uid === currentUid)
);
Consider using the Object.values() method instead, to extract the "parent heading" for the supplied uid.
Taking this approach, you can iterate the values of data, and filter those section values that contain items matching the uid. In the answer below, this is done via:
return items.some(item => item.content.uid === currentUid)
Finally, you can map() the filtered sections to acquire the corresponding heading(s) of section with matching uid items:
function findHeading(data, uid) {
return Object.values(data).filter(section => {
// Find any item with matching uid in this section, filter this section accordingly
return section.items.some(item => item.content.uid === currentUid)
})
.map(section => {
// Map heading from any sections matching item uid
return section.heading
});
}
const data = {
"3c5671fde44f44f9ad59d59eb810d87e": {"heading": "Heading 1","items": [{"content": {"uid": "4fcd5f4af7a448d48463d4e0a11297d9"}},{"content": {"uid": "31f975440a0a431592e127b2891cd142"}}]},"ea80e8315b554c9bb40958a6cacf4b0c": {"heading": "Heading 2","items": [{"content": {"uid": "d6de8db4c2a74da6915a44d3964277d6"}}]}
}
const currentUid = "d6de8db4c2a74da6915a44d3964277d6";
console.log(findHeading(data, currentUid))

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.

Categories

Resources