React rendering a loop inside a loop - javascript

Trying to loop inside a loop and getting error: value.forEach is not a function.
Dont know how to write this code inside a render
render(){
return(
Object.entries(this.props.detailOras).map(([key, value])=>{
return(
<div className="flex-row">
<div className="flex-cont">
<div>Laikas</div>
<div>Temperatūra </div>
<div>Vėjas</div>
<div>Krituliai</div>
</div>
{value.forEach(day => {
return(
<div className="flex-cont">
<div>{day.forecastTimeUtc.slice(11,16)}</div>
<div>{day.airTemperature} </div>
<div>{day.windSpeed}</div>
<div>{day.totalPrecipitation}</div>
</div>
)
})}
</div>
)
}
))}

Below should work provided value is populated as an array in later stages.
render(){
return(
Object.entries(this.props.detailOras).map(([key, value])=>{
return(
<div className="flex-row">
<div className="flex-cont">
<div>Laikas</div>
<div>Temperatūra </div>
<div>Vėjas</div>
<div>Krituliai</div>
</div>
{(value.forecast || []).map(day => {
return(
<div className="flex-cont">
<div>{day.forecastTimeUtc.slice(11,16)}</div>
<div>{day.airTemperature} </div>
<div>{day.windSpeed}</div>
<div>{day.totalPrecipitation}</div>
</div>
)
})}
</div>
)
}
))}

Related

Why does my id i get from next js router.query return undefined on refresh? [duplicate]

This question already has answers here:
useRouter/withRouter receive undefined on query in first render
(9 answers)
Closed 5 months ago.
I am using the id gotten from next router.query to render elements dynamically it works when i access the room from next/link but when i refresh the page it throws this error
here is my code (note: roomId here was gotten from const {roomId} = router.query):
return (
<>
<div className={styles.header}>
<div className={styles.title}>{rooms[roomId].name}</div>
<div className={styles.headerCon}>
<div className={styles.roomUsers}>
<AvatarGroup
max={3}
total={Object.keys(rooms[roomId].users).length}
>
{Object.keys(rooms[roomId].users).map((user) => (
<Avatar
key={user + Math.random()}
alt={users[user].name}
src={users[user].profile_pic}
/>
))}
</AvatarGroup>
</div>
<div className={styles.headerIcons}>
<div className={styles.react}>
<AddReactionOutlinedIcon />
</div>
<div className={styles.notif}>
<NotificationsNoneOutlinedIcon />
</div>
<div className={styles.more}>
<MoreHorizOutlined />
</div>
</div>
</div>
</div>
{user.name === rooms[roomId].createdBy.name ? (
<div className={styles.begin}>
{!roomActive ? (
<button onClick={handleStartSession}>Start</button>
) : (
<button onClick={handleEndSession}>End</button>
)}
</div>
) : (
""
)}
<div className={styles.participators}>
<div className={styles.pAvatars}>
<Avatar
alt={rooms[roomId].createdBy.name}
src={rooms[roomId].createdBy.profile_pic}
/>
<div className={styles.userName}>{rooms[roomId].createdBy.name}</div>
<div className={styles.userRole}>Admin</div>
<div>
<audio autoPlay ref={userAudio} />
{peers.map((peer, index) => {
return <Audio key={index} peer={peer} />;
})}
</div>
</div>
{Object.keys(rooms[roomId].users)
.filter((user) => users[user].name !== rooms[roomId].createdBy.name)
.map((user) => (
<div className={styles.pAvatars} key={Math.random() + user}>
<Avatar alt={users[user].name} src={users[user].profile_pic} />
<div className={styles.userName}>{users[user].name}</div>
<div className={styles.userRole}>Admin</div>
</div>
))}
</div>
</>
);
}
As you can see much of what i am rendering on this page depends on that id, so can someone please help?
You try to access the query parameter before its state is ready. There is a workaround to solve this problem.
import { useRouter } from 'next/router';
const router = useRouter();
useEffect(() => {
if (router.isReady) {
// Do your stuff
// for example: assign query param to a state
}
}, [router.isReady]);

How do I get the rendered ID to use globally as a variable to send an API request in React?

How do I get the rendered <li> class name item.imdbID or the key item.imdbID to use in another API request? The API needs the ID to search correctly but I am having trouble extracting this information to use globally on my onClick method seasonsList(). I'm extremely new to React and am still trying to wrap my head around the logic!
This is the code of my render method in React:
render() {
if (this.state.screenType === 'init'){
return (
<div>
<input type="text" onChange={this.textInput}></input>
<button onClick={this.search}>search</button>
<div className="results">
{this.state.loading ? (
<div>search for a series</div>
) : (
<div>
results:
<ul>
{seriesArrayTitles.map(item=> (
<li key={item.imdbID} className={item.imdbID} onClick={this.seasonsList}>{item.Title}</li> )
)}
</ul>
</div>
)}
</div>
</div>
);
}
This is very simple to do. You can just provide this value as an argument to your this.seasonsList function.
seasonsList = (id) => {
// doing something with the id
}
render() {
if (this.state.screenType === 'init') {
return (
<div>
<input type="text" onChange={this.textInput}></input>
<button onClick={this.search}>search</button>
<div className="results">
{this.state.loading ? (
<div>search for a series</div>
) : (
<div>
results:
<ul>
{seriesArrayTitles.map((item) => (
<li
key={item.imdbID}
className={item.imdbID}
onClick={() => this.seasonsList(item.imdbID)}
>
{item.Title}
</li>
))}
</ul>
</div>
)}
</div>
</div>
);
}
}

How can I render multiple elements after an inline condition using short circuit evaluation?

Using a short circuit evaluation in a functional component (with hooks):
const Filters = () => {
const [options, setOptions] = useState([]);
return (
<div className="row">
{options.length > 0 && (
<div className="col-md-3">
<CustomComponent />
</div>
)}
</div>
)
}
Is there a way to render multiple elements right after an inline if condition?
{options.length > 0 && (
<div className="col-md-3">
<CustomComponent />
</div>
<div className="col-md-3">
<SecondComponent />
</div>
)}
Code above doesn't work, react throws an error. options array is filled after a promise resolved from useEffect(). That's why i've added this check, to display elements only when a promise resolved.
UPDATED CODE for #wentjun:
return (
{options.length > 0 && (
<div className="row">
<div className="col-md-3">
<CustomComponent />
</div>
</div>
)}
)
This throws a syntax error.
I think the error is due to returning two react elements. Try wrapping then in fragment
{options.length > 0 && (
<>
<div className="col-md-3">
<CustomComponent />
</div>
<div className="col-md-3">
<SecondComponent />
</div>
</>
)}
You should wrap the elements in React Fragments. The reason being, React elements are rendered via a single root node element. Wrapping it in Fragments will allow you to group the elements without adding additional nodes.
return (
<div className="row">
{options.length > 0 && (
<>
<div className="col-md-3">
<CustomComponent />
</div>
<div className="col-md-3">
<SecondComponent />
</div>
</>
)}
</div>
)

Does anyone know why all of my elements are being rendered in a single column as if it were a <navbar>?

My component is being rendered in a single column equal to the photo I attached, but it is wrong, it was to be a 5x4 array.
edi1: In an old version of the code I did not have this problem, however I received some props, and since I have to constantly change the contents of the Component, I thought it was good to use state.
render() {
return (
<div className="App">
<Navbar onChange={this.onChange.bind(this)} />
<div className="container mt-10">
<div className="row">
{<RecipeItem list={this.state.searchString} />}
</div>
</div>
</div>
);
}
}
File RecipeItem.js
const RecipeList = ({ searchString }) => {
return(
<div>
<img className="card-img-top img-fluid" src={searchString.thumbnail} alt={searchString.title} />
<div className="card-body">
<h5 className="card-title">{searchString.title}</h5>
<p className="card-text">
<strong>Ingredients: </strong>{searchString.ingredients}
</p>
</div>
</div>
)
}
const RecipeItem = (props) => {
return (
<div className="col-sm-3 mt-4">
<div className="card">
{props.list && props.list.map((searchString, index) =>
<RecipeList searchString={searchString} key={index} />
)}
</div>
</div>
)
}
You're applying col-sm-3 before iterating on each element, you should apply the class on each iteration like this :
const RecipeItem = (props) => {
return (
props.list && props.list.map((searchString, index) =>
<div className="card col-sm-3 mt-4">
<RecipeList searchString={searchString} key={index} />
</div>
)
)
}

How to pass dynamic value to div element and then access it - React ?

I'm mapping all of my files
_renderItems = files =>
files
? files.map((item, i) => {
return <ProjectItemUser {...item} key={i} index={i} />;
})
: null;
and then I'm trying to display it ProjectItemUser
class ProjectItemUser extends Component {
render() {
return (
<div>
<div className="book_item">
<div className="book_header">
<h2>{this.props.name}</h2>
</div>
<div className="book_this">
<div className="book_author">{this.props.subject}</div>
<div className="book_bubble">
<strong>Study: </strong> {this.props.study}
</div>
<div className="book_bubble">
<strong>Grade: </strong> {this.props.grade}
</div>
<FontAwesomeIcon icon="trash" id="trash" />
</div>
</div>
</div>
);
}
}
This basically displays all the files, and each file is its own separate row. I would like to assign value to div element on each iteration, so I can control which file has been clicked.
I can access my id with: this.props._id
Should this be done using refs and if so, how ?
You should pass onClick function as parameter
_renderItems = files =>
files
? files.map((item, i) => {
return <ProjectItemUser {...item} key={i} index={i} onClick={() => { console.warn(item) } />;
})
: null;
class ProjectItemUser extends Component {
render() {
return (
<div>
<div className="book_item">
<div className="book_header">
<h2>{this.props.name}</h2>
</div>
<div className="book_this">
<div className="book_author">{this.props.subject}</div>
<div className="book_bubble">
<strong>Study: </strong> {this.props.study}
</div>
<div className="book_bubble">
<strong>Grade: </strong> {this.props.grade}
</div>
<FontAwesomeIcon icon="trash" id="trash" />
<Button onClick={this.props.onClick} label="Click on me" />
</div>
</div>
</div>
);
}
}

Categories