I'm trying to use use Object.keys in a map function but i'm getting keys based on map value variable but it's giving me error my data object as you can see i'm trying to get the keys of Display and coin value from map variable and the coin value is in the array at the end but it's giving me error
in short i'm want to get the keys of every object in display child object and display child key will be from my coin name array so i don't have to hardcode it
{this.props.crypto_head_coins.map(coin => {
return (
<div key={coin} className="crypto_head">
<span>{coin} </span>
{console.log(Object.keys(this.props.crypto_head_data.DISPLAY.coin))}
<p>{this.props.crypto_head_data.DISPLAY.BTC.USD.PRICE}</p>
</div>
);
})}
This does not work, because DISPLAY is expected to have a literal key called "coin".
Object.keys(this.props.crypto_head_data.DISPLAY.coin);
This will work, because you are referencing the variable coin as a possible key in DISPLAY.
Object.keys(this.props.crypto_head_data.DISPLAY[coin]);
{
this.props.crypto_head_coins.map(coin => {
return (
<div key={coin} className="crypto_head">
<span>{coin}</span>
{console.log(Object.keys(this.props.crypto_head_data.DISPLAY[coin])}
<p>{this.props.crypto_head_data.DISPLAY.BTC.USD.PRICE}</p>
</div>
);
});
}
Related
I have the following dataset that I am trying to get values from, using JavaScript.
My code is as follows:
{companies.map(({ matches }) => (
<Company
key={matches}
name={matches}
symbol={matches}
/>
))}
I have tried to get the values by providing the key in the map function as follows:
name={matches['2. name']}
My question is, what syntax should I be using to get a value where the key has spacing and full-stops?
Your issue is this:
companies.map(({ matches }) => { … })
^^^^^^^^^^^
This is saying that for each item in the companies array, use a property named matches (through parameter destructuring), which, from what you're showing, doesn't exist.
Instead, I think you meant this:
companies.map(( matches ) => { … });
// or shorter:
// companies.map( matches => { … });
I am building a test app to learn more about React and I have made an API call which gets a huge JSON object.
I was able to break this json into the parts that I need and now I have 10 arrays of 3 props each. I am able to send these 10 arrays in 3 props to another component, which needs to use these 3 props 10 times and render a div class Card each.
I can console.log(this.props) and it shows 10 different arrays with 3 props each,however, I cannot produce a same element 10 times.. I tried using map() but since my array is initially undefined, map() is not able to function properly either. Is there any thing in react like *ngFor in Angular ?
What is the best way to go about this?
*EDIT
Here's more code guys. Sorry still noobie here..
ERROR : this.props.map is not a function
return(
<div>
{this.props.map((data,i)=>{
return(
<li key={i}>{data.likes}</li>
);
*EDIT 2
Soo I tried running map function with an if condition but the code still breaks the very moment the condition gets true..
render() {
if(this.props.url !== undefined){
this.props.map((data,i) =>{
return <li key={i}>{data.likes}</li>
})
}
My state method is :
state = {
userId: undefined,
likes: undefined,
url: undefined
}
and im setting my values on each data stream as follows :
const pics = await fetch(`${base_url}?key=${api_key}&q=${query}
&img_type=photo&per_page=12`).then(response => {
return response.json();
})
pics.hits.map((data) =>{
return this.setState({
userId: data.user_id,
likes: data.likes,
url: data.webformatURL
})
})
this.props won't have map, it's not an array. It's an object with a property for each property passed to your component. For instance:
<YourComponent foo="bar"/>
...will have this.props.foo with the value "bar".
So if you're passing an array to your component, like this:
<YourComponent theArrayProperty={[{likes: 42},{likes:27}]} />
...then you need the name of that property:
return (
<div>
{this.props.theArrayProperty.map((data,i) => {
return (
<li key={i}>{data.likes}</li>
);
})}
</div>
);
Side note: You can use a concise arrow function for the map callback instead:
return (
<div>
{this.props.theArrayProperty.map((data,i) => <li key={i}>{data.likes}</li>)}
</div>
);
...and no need for the () if you put the opening tag on the line with return (you can't leave off the ( if it's on the next line, but you probably knew that):
return <div>
{this.props.theArrayProperty.map((data,i) => <li key={i}>{data.likes}</li>)}
</div>;
...but that's a matter of style.
With little information that you have provided, my guess is that code fails at map() when you try to use it with undefined value.
Try adding a conditional check to render
{props && props.map([RENDER CODE HERE])}
You can just make simple if statement to check if the array is not undefined, and then pass it to map function.
Another option is to set a defaultProps for an empty array.
MyComponent.defaultProps = {
arrProp: []
};
If I have two objects:
keyedCustomers
item
Both of those objects contain a value I need because I need to check a condition with the object item and then display stuff from keyedCustomers.
In keyedCustomer I have this: _id: "5954aa0433979b24e825de77".
And in item there's this: customer: "5954aa0433979b24e825de77".
As you can see, the values are exactly the same.
I've heard from my friends that I could use Lodash and do something like: _.keyby(blablabla), but I'm not really sure.
All help I can get is much appreciated.
Update! Need to add some code
So basically here's my condition:
if (item.level == 0) {
return (
<div>
<p>Denna användare har inte accepterat: {need name-value from object keyedCustomer}</p>
</div>
)
}
If the value at item.level is equal to 0 a div need's to pop up. And the object item does not have the key name, therefor I need to find a way to merge them.
If keyedCustomers is an array of objects keyedCustomer, each having a name property, then you can use _.find to look up the customer name based on a key that is provided by the customer property of item:
if (item.level == 0) {
let thisCustomer = _.find(keyedCustomers, { '_id': item.customer});
return (
<div>
<p>Denna användare har inte accepterat: {thisCustomer.name}</p>
</div>
)
}
In my aurelia app, I need to display a list of elements. For performance reasons, these elements are stored as a javascript object instead of an array. That is what the object looks like :
var x = {
0 : {...},
3 : {...},
5 : {...},
}
Here is the part of the template where I display these elements :
<template>
<ul>
<li repeat.for="property of object | ObjectToArray">
${ property.text }
</li>
</ul>
</template>
As you can see, I'm currently using a value converter to be able to iterate over my object properties. The value converter simply converts the object to an array :
export class ObjectToArrayValueConverter {
toView(data : {[key : string] : any}) : any[] {
var array = [];
for (var key in data) {
array.push(data[key]);
}
return array;
}
}
This solution works very well as long as properties do not get removed or added to the object after the list has been rendered for the first time. The reason is that the value converter only gets called once.
In my case, however, I need my list to stay up to date whatever happens.
I know I could create a function that could be manually called every time the object is modified, but that would add some unwanted complexity in business logic.
Is there an aurelia functionality that coud help me achieve what I want ? I could not find any help in the docs. Thank you !
You can get the keys using Object.prototype.keys and call Array.prototype.map on it to get an array every time you want to list it out.
var obj={...}; //Object with many keys
var genArray = Object.keys(obj).map(function(key){return obj[key];})
//Using as a function
function getKeysAsArray(obj){
if(!obj){
return [];
}
return Object.keys(obj).map(function(key){return obj[key]});
}
There's an easier strategy, as shown in the docs:
export class KeysValueConverter {
toView(obj) {
return Reflect.ownKeys(obj);
}
}
Usage:
<p repeat.for="greeting of friends | keys">${greeting}, ${friends[greeting].name}!</p>
Quick one, I've 2 arrays/ objects. One contains all items the other contains selected ID's from the first array.
My question is, what is the best way to loop through both arrays find selected items from the second array and if they are true append data to first array. What I'm trying to do is append true to the first array if the ID's match.
For example something like this:
this.categories.filter(
category => {
this.user.category_ids.filter(
selected => {
if(selected == category._id) {
var data = {'selected': true};
category.push(data);
}
}
);
console.log(category);
}
);
At the moment I'm looping through categories object then through user.category_ids and if the ID's match I want to append selected: true to first array object, if this makes sense. I get error:
core.es5.js:1084 ERROR TypeError: category.push is not a function
Which I don't understand why. I've also tried splice.
Also to me this doesn't seem like best approach, because I've 12 items in first array. And if all 12 are selected, second array will have 12 items. So looping through 12 * 12 to me is little expensive, memory wise.
You can try something like this:
this.categories.map(category => {
category.selected = this.user.category_ids.indexOf(category._id) !== -1;
return category;
});
if (selected == category._id) {
category['selected'] = true;
/* you can build a interface for category
* or declare category as any
* then you can write it as the below
*/
// category.selected = true;
}
push is to add a new item to an array.
Kindly clarify if categories is an array of objects? If yes then you cant use push to add a new object since each element in the categories is an object and object don't have push method. Add new property to object instead using
category.selected=true or
category['selected']=true;
Assumptions:
this.user.category_ids is a 'array of objects' as you are using 'category._id'.
if ids match you want to add a key 'selected' whose value is true , to that object whose id is matched .
Solution:
- You are getting this error category.push is not a function because category is an object not an array ,push only works with array.
if(selected == category._id) {
category['selected']=true;
}