Display image from .map array (React) - javascript

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

Related

map() method on multi dimensional array in gatsby/react, getting error while trying to wrap inner loop in div

i want to display three posts per row in a gatsbyjs web page. i am having an array of posts, if i were to display using columns it would be just applying the multiline class on the posts container div. but i am using tiles layout built-in in bulma css, unfortunately that don't support multiline likes columns do.
so i have to wrap every three posts in a div with class 'tile'. for which i split the array into chunks of 3 size each (as suggested by someone here, thanks to him) now it boiled down to looping through a two dimensional array.
now the problem is i am getting syntax error when trying to wrap the inner loop in a div (i am new to javascript/es6 and react/gatsby, so i am hoping someone here would help me out) below is the code, i commented out the divs for which i am getting error. so how to wrap the inner loop in a div in gatsby/react. TIA
return(
<div className="tile is-ancestor">
{chunks.map((chunk)=> {
return (
//<div class="tile">
chunk.map((edge) => {
return(
<div className="tile is-parent is-4">
<div className={`tile is-child notification ${edge.node.frontmatter.type}`}>
<p className="is-7">{edge.node.frontmatter.date}</p>
<h2 className="subtitle is-5">{edge.node.frontmatter.title}</h2>
<p>{edge.node.excerpt}</p>
</div>
</div>
)
}
)
//</div>
)
})}
</div>
);
You would need to wrap the code inside that div in curly braces { } to be valid JSX. Just like you did with the first chunks.map.
return(
<div className="tile is-ancestor">
{chunks.map((chunk)=> {
return (
<div class="tile">
{
chunk.map((edge) => {
return(
<div className="tile is-parent is-4">
<div className={`tile is-child notification ${edge.node.frontmatter.type}`}>
<p className="is-7">{edge.node.frontmatter.date}</p>
<h2 className="subtitle is-5">{edge.node.frontmatter.title}</h2>
<p>{edge.node.excerpt}</p>
</div>
</div>
)
}
)
}
</div>
)
})}
</div>
);

How do I highlight 1 image at a time in an image gallery using react or css

I'm creating an image selection modal, and want the user to only choose 1 image. I know how to get that unique image and push that data, but I don't know how to highlight one individual image at a time.
For example, if the user clicks on 1 image that image should have a blue border around it, but if they click on another image, then the 2nd image will have a blue border and the other image will lose that border.
There could potentially be hundreds of images, so I can't write it out by hand. How can I do this?
Here's some of my code, pretty basic stuff.
imageChosen = (e) => {
console.log(e)
};
<div className={classes.imageList}>
<div className={classes.imageWrap}>
<img onClick={(e) => this.imageChosen(e.target.src)} src="smallfamilyadv.jpg" alt="" />
</div>
<div className={classes.imageWrap}>
<img onClick={(e) => this.imageChosen(e.target.src)} src="BugzPlaypark.jpg" alt="" />
</div>
<div className={classes.imageWrap}>
<img onClick={(e) => this.imageChosen(e.target.src)} src="play-park-500x500.jpg" alt="" />
</div>
</div>
Use a state, and an array list
state = {
imageChosen : undefined;
}
render() {
const img = ["smallfamilyadv.jpg","BugzPlaypark.jpg", "play-park-500x500.jpg"]
return <div className={classes.imageList}>
{img.map((e,i)=> {
return <div key={i} className={this.state.imageChosen === e ? classes.imageWrapSelected : classes.imageWrapNormal}>
<img onClick={(e) => this.setState({imageChosen:e.target.src})} src={e} alt={e} />
</div>
})}
</div>
}

Pass object as parameter in Link

I am using <Link> and trying to pass in my thumb_id (if I console log it is just a string value) to my editvideo page as a parameter. How do I accomplish this?
Code Snippet
const { thumbnail, _id } = this.props;
return thumbnail.map(thumb => {
console.log(thumb._id);
return (
<div key={thumb._id} className="row__inner">
<Link to="/editvideo/:thumb._id">
<div className="tile">
<div className="tile__media">
<img
className="tile__img"
id="thumbnail"
src={thumb.thumbnail}
alt=""
/>
</div>
</div>
</Link>
</div>
Params using temp literal
Console log of thumb_id
You can use a template literal to insert the value of the variable in the string.
<Link to={`/editvideo/${thumb._id}`}>

How to check condition inside map without putting a div

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.

React how to get item props from event.currentTarget

Does react have a clean way to get the this.props.values from a list item?
I basically want to get the current items props so I can populate a modal dialog with the data. as per below functions the custom props that I specify like 'id' are accessible, but I really would like to do something like this and have all the props
event.currentTarget.this.props.note
Handler
clicker(event){
console.log('clicking the clicker');
console.log(event.currentTarget.id);
this.setState({isEdit: true});
console.log(this.state.isEdit);
}
View
<div id={this.props.id} onClick={this.clicker} className="aui-item page-card off-track notecards">
<div className="project-details">
<div className="card-container">
<div className="left">
<h6>Title</h6>
<span>{this.props.note.content}</span>
<h6 className="compact">Last status report</h6>
<span>{this.props.note.updatedAt}</span>
</div>
<div className="right">
<span>something</span>
</div>
</div>
</div>
</div>
You can directly access props inside clicker
clicker(event){
console.log('clicking the clicker');
console.log(this.props.id);
this.setState({isEdit: true});
console.log(this.state.isEdit);
}
In this case it would be better to create separate component. In my opinion not necessary to create big huge views.
So, your component should be like this:
function Item({
id,
updatedAt,
content,
onClick,
}) {
// We should pass `id` variable to `onClick` handler.
return (
<div onClick={() => onClick(id)} className="aui-item page-card off-track notecards">
<div className="project-details">
<div className="card-container">
<div className="left">
<h6>Title</h6>
<span>{content}</span>
<h6 className="compact">Last status report</h6>
<span>{updatedAt}</span>
</div>
<div className="right">
<span>something</span>
</div>
</div>
</div>
</div>
);
}
Or, if you don't want to use separate component, you can access this.props variable from clicker event handler:
clicker(event){
// this.props are accesible here.
this.setState({isEdit: true});
}

Categories