I am trying to put a "col-sm-6" inside a row with checking a condition . But when null value is coming it is returning a blank div with ".col-sm-6" class, I need to hide that class when value is null.
<div className="row">
{attribute.attributeValues.map((list, index) =>
<div className="col-sm-6" >
{list.isSelected === 1 ?
<div className="style">
<span><i className="fa fa-check"></i>{list.tag_value}</span>
</div>:''
}
</div>
)}
</div>
this is giving results like:
like:
<div class="row">
<div class="col-sm-6">Some Value</div>
<div class="col-sm-6"></div>
<div class="col-sm-6"></div>
</div>
But I want:
<div class="col-sm-6">Some Value</div>
<div class="col-sm-6">Some Value</div>
<div class="col-sm-6">Some Value</div>
You can make use of React.Fragment like
<div className="row">
{attribute.attributeValues.map((list, index) =>
<React.Fragment key={index}>
{list.isSelected === 1 ?
<div className="style">
<span><i className="fa fa-check"></i>{list.tag_value}</span>
</div>:''
}
</React.Fragment>
)}
</div>
According to the docs:
A common pattern in React is for a component to return multiple
elements. Fragments let you group a list of children without adding
extra nodes to the DOM.
Second method to remove the wrapping {} in the ternary condition
<div className="row">
{attribute.attributeValues.map((list, index) =>
list.isSelected === 1 ?
<div className="style">
<span><i className="fa fa-check"></i>{list.tag_value}</span>
</div>: null
)}
</div>
Actually, you just need to use filter (MDN documentation) before the map. You can do something like:
attribute.attributeValues.filter(list => list.tag_value).map(...
That way, with filter, you return a new Array in which only items with a "real" list.tag_value value.
In JavaScript, everything without a "Value" is False (JavaScript Booleans). That means that the filter above will filter out any list.tag_value equal to: undefined, null, empty String ("") or Number equal to 0.
Related
setForecast(res2.data.list.map(item => [
<div className="each_data_point">
<li className="date_time" key={item.dt_txt}>{`Date & Time: ${item.dt_txt}`}</li>,
<img className="icon" key={item.weather[0].icon}>{`https://openweathermap.org/img/w/${item.weather[0].icon}.png`}</img>,
<li className="main_temp" key={item.main.temp}>{`Temp: ${item.main.temp}`}</li>
</div>
]
))
......
return (
<div>
<div className="five_day_forecast">
<div className="temp_body">
// Display here with Date/Time & Main Temp.
<p>{forecast}</p>
</div>
</div>
Is it possible to render an image from array.map() within React. When I run this, the DOM clears completely to white screen.
Using src in the img tag to render image
<img className="icon" key={item.weather[0].icon} src={`https://openweathermap.org/img/w/${item.weather[0].icon}.png`} />
And put the key in div instead in the children.
Not sure why you are doing it, but setting JSX in your state seems strange.
Try something like this, assuming res2.data.list has the list of values.
<div className="five_day_forecast">
<div className="temp_body">
// Display here with Date/Time & Main Temp.
<p>
{res2.data.list && res2.data.list.length >0 && res2.data.list.map(item => [
<div className="each_data_point">
<li className="date_time" key={item.dt_txt}>{`Date & Time: ${
item.dt_txt
}`}</li>
,
<img
className="icon"
key={item.weather[0].icon}
>{`https://openweathermap.org/img/w/${
item.weather[0].icon
}.png`}</img>
,
<li className="main_temp" key={item.main.temp}>{`Temp: ${
item.main.temp
}`}</li>
</div>
])}
</p>
</div>
</div>
Putting markup in state is a weird anti-pattern. State is really there to just store data not markup. You can use a function to create the JSX from mapping over the data.
You should be adding the source of the image to the src attribute of the img element.
Keys should be added to parent elements.
const imgSrc = `https://openweathermap.org/img/w/${item.weather[0].icon}.png`;
<img src={imgSrc} />
// `fetch` your data, and add it to state
setForecast(res2.data.list);
// `map` over the data and create the markup
function getMarkup() {
const imgSrc = `https://openweathermap.org/img/w/${item.weather[0].icon}.png`;
return forecast.map(item => {
<div className="each_data_point" key={item.dt_txt}>
<li className="date_time">{`Date & Time: ${item.dt_txt}`}</li>,
<img src={imgSrc} className="icon" />,
<li className="main_temp">{`Temp: ${item.main.temp}`}</li>
</div>
});
}
return (
<div>
<div className="five_day_forecast">
<div className="temp_body">
// Call the function to return the markup
// build from state
{getMarkup()}
</div>
</div>
);
I need to return the following code in ReactJS x amount of times. I am trying to populate a card with names based on how many people there are in a team.
So if x was 5, I would need that to appear 5 times.
<div className="row align-items-center justify-content-center m-b-10">
<h5>Name goes here</h5>
</div>
This is the type of object I'm dealing with:
Is there a clean way of doing this?
First, it depends on how your data is defined, for example, if the names are in an array, you can create an array of JSX elements that contain each , you can use .map()
Just use:
const x = 5
Array(x).fill().map((el, index) =>
<div className="row align-items-center justify-content-center m-b-10" key={index}>
<h5>Name here</h5>
</div>
)
This is not ideal because you can also iterate over the array of names itself, and get the same result, even cleaner.
<div>
{
arrayOfNames.map((el, index) => (
<div className="row align-items-center justify-content-center m-b-10" key={index}>
<h5>`${el.first_name} ${el.last_name}`</h5>
</div>
))
}
</div>
Assuming you got all of the people names in an array. You can use map over the array when rendering`:
{ yourObject.map((person, idx)=>(
<div className="row align-items-center justify-content-center m-b-10" key={idx}>
<h5>{person.first_name + " " + person.last_name}</h5>
</div>
)}
(Of course, make sure this code is wrapped with another element)
This question already has answers here:
How to create unique keys for React elements?
(16 answers)
Closed 2 years ago.
I'm making a simple To Do list in React and even though I have a key property, I am still getting the error "Each child in a list should have a unique "key" prop.".
Here is my JSX:
<div className="list">
<ul>
{updatedList.map((item, index) => {
return (
<div>
<li key={index}>{item}</li><button>delete</button>
</div>
)
})}
</ul>
</div>
Is the index of my updatedList not enough for a key value? How would I go about appending something like "li_ + {index}" to each key?
I would suggest to not use the index as key for your todo app. Chances are you will delete a certain item from your todo list. This will mess up your UI if you use index as a key. You can create a function like generateID() which returns you a unique key.
You can use something like Math.random() or Date Api or combination of both for unique key generation.
You need to assign the key property to the parent container. On the root element.
<div className="list">
<ul>
{updatedList.map((item, index) => {
return (
<div key={index}>
<li>{item}</li><button>delete</button>
</div>
)
})}
</ul>
</div>
You can use a tree techinque, like as
<div id="A" className="list">
<ul id="B" >
{updatedList.map((item, index) => {
return (
<div>
<li key={'A'+'B'+index}>{item}</li><button>delete</button>
</div>
)
})}
</ul>
</div>
<div key={index}>
<li >{item}</li><button>delete</button>
</div>
Key should be on the first node
It still marks the error because you're putting the key tag not on the root element, but on li which is a child of div, while you should put it on the div element.
<div className="list">
<ul>
{updatedList.map((item, index) => {
return (
<div key={index}>
<li>{item}</li><button>delete</button>
</div>
)
})}
</ul>
</div>
``\
I need to know what's the difference between this code
{this.state.products &&
this.state.products.map((product, index) => (
<div key={index}>
<Subd
name={product.name}
price={product.price}
info={product.info}
image={product.image}
handleShow={this.showProduct}
handleTotal={this.calculateTotal}
/>
</div>
))}
and looping the div inside <Sudb/> component like
this.state.products &&
this.state.products.map((product, index) => (
<div className="row form-group">
<div className="col-sm-2">
<img
className="card-img-right flex-auto d-none d-lg-block"
alt="Thumbnail+{index}"
src={product.image}
/>
</div>
<div className="col-sm-6">
<h4>
{product.name}: ${product.price}
</h4>
<button className="btn btn-outline-primary" onClick={this.showInfo}>
show info
</button>
</div>
<div className="col-sm-4 text-right">
qty: {this.state.qty}
<br />
<button className="btn btn-outline-primary" onClick={this.add}>
{" "}
+1{" "}
</button>
<button
className="btn btn-outline-primary"
onClick={this.subtract}
disabled={this.state.qty < 1}
>
{" "}
-1{" "}
</button>
</div>
</div>`
in the above case if I update the quantity its affecting all the three objects but in the first case it's working fine. Can anyone explain what's the exact difference between both? Sandbox link Sandbox
In the second code I have made <Subd/> component code directly
The problem from what i can see in the code sample provided with the second sample provided is the following.
You are using the same piece of state for all products. so when you update this.state.qty for one row it updates all of them simultaneously.
The reason it does work when you separate it is because then each row has its own state that you can store individual quantities in.
If you did feel the need to not seperate out that code you could create an array on state for each of the qty's. and change up the subtract method to accept an index that it can use to access a certain rows qty state on the qty state array.
To pass in parameters to onclick you have to wrap it in a arrow function so it does not run automatically when the page mounts like so
onClick={() => {someFunction(param)}
I need to add a className based on the condtion in flatmap looping.
previousDataJson
var previousDataJson = {
"Queue1": "req_ares_crt1",
"Queue2": "req_cres_crt2",
"Queue3": "req_rres_crt3",
}
{_.flatMap(previousDataJson, (value,key) =>
<div className="columns">
<div className="column">
<div className={"transaction__info " + ({if(previousDataJson[key] != newDataJson[key]){ return "bg-blue" }})}>
<span className="transaction__title">
{key}:
</span>
<div className="transaction__desc">
<span style={{wordBreak:'break-all'}}>
{value}
</span>
</div>
</div>
</div>
</div>
)}
I need to add the classname dynamically based on the conditions.
className={"transaction__info" + (previousDataJson[key]!==newDataJson[key]?" bg-blue":"")}
Are you taking an error or isn't it compiling?
Or
You can use style object instead of appending classnames