React Nested Foreach on Return - javascript

Trying to use nested foreach in React.
But not working at all;
return (
{category.map((item, i) => (
<div className="col-sm-12">
<h5>{item.title}</h5>
</div>
item.data.map((it, iv) => (
<div class="col-6">
<ProductCard {...it} />
</div>
))
))}
)

You are using .map higher order function
you need to wrap in in fragment so React Will know that it's a JSX or wrap it on div
Introduction to JSX
Learn Fragment React
return (
<>
{category.map((item, i) => (
<div className="col-sm-12">
<h5>{item.title}</h5>
</div>
item.data.map((it, iv) => (
<div class="col-6">
<ProductCard {...it} />
</div>
))
))}
</>
)

if you want to render nested array maybe it will work
return (
<> // Put Wrapper
{category.map((item, i) => (
<> // put an empty fragment to contain title div and another map
<div key={i} className="col-sm-12"> // dont forget to put key props
<h5>{item.title}</h5>
</div>
{item.data.map((it, iv) => ( // wrap another map on '{}' because it inside jsx
<div key={iv} class="col-6"> // dont forget to put key props
<ProductCard {...it} />
</div>
)}
</>
)}
</>
)
you can also change <> to div or any if you want to style it. And dont put // comment on jsx, it just my mark to explain this code

Related

Mapping over 2 arrays

I have 2 arrays of objects: meeting and room and a Card component with some fields to be completed by them.
I tried to map over the arrays in order to access the elements from both of them at the same time but it returns the Card component six times(the number of the elements in the array of Room)
<div className="topCards">
{room.map((dataObj) => {
return (
<div>
{meeting.map((meetObject) => {
return (
<div className="item">
<Card3
className="card3"
teamName={meetObject.name}
roomName={dataObj.name}
time={dataObj.time}
data={dataObj.data}
capacity={dataObj.capacity}
/>
</div>
);
})}
</div>
);
})}
</div>
So, my question is how can I return the Card element with elements from both cards
What let you think that it would work like that?
Just use the index parameter of Array.prototype.map
<div className="topCards">
<div>
{meeting.map((meetObject, i) => {
return (
<div className="item">
<Card3
className="card3"
teamName={meetObject.name}
roomName={dataObj[i].name}
time={dataObj[i].time}
data={dataObj[i].data}
capacity={dataObj[i].capacity}
/>
</div>
);
})}
</div>
</div>

Cards inside the grid-container: each child in a list should have a unique "key" prop

What I`m doing wrong?It also says: "Check the render method of Card" , which is here:
<div className="grid-container">
{pokemonData.map((pokemon, i) => {
console.log(pokemon.id) // unique numbers are here
return <Card key={pokemon.id} pokemon={pokemon} />
})}
</div>
Card component itself:
function Card({ pokemon }) {
return (
<div className="card">
<div className="card__image">
<img src={pokemon.sprites.front_default} alt="Pokemon" />
</div>
<div className="card__name">
{pokemon.name}
</div>
<div className="card__types">
{
pokemon.types.map(type => {
return (
<div className="card__type" style={{backgroundColor: typeColors[type.type.name]}}>
{type.type.name}
</div>
)
})
}
</div>
<div className="card__info">
<div className="card__data card__data--weight">
<p className="title">Weight:</p>
<p>{pokemon.weight}</p>
</div>
<div className="card__data card__data--height">
<p className="title">Height:</p>
<p>{pokemon.height}</p>
</div>
<div className="card__data card__data--ability">
<p className="title">Abilities:</p>
{/* {console.log(pokemon.abilities)} Temporary for dev puprose */}
{pokemon.abilities.map(ability => <p>{ability.ability.name}</p>
)}
</div>
</div>
</div>
);
}
export default Card;
You can use the index of the array may be your data is having some kind of duplicate. It is recommended that you pass a key prop whenever you are returning a list.
<div className="grid-container">
{pokemonData.map((pokemon, i) => {
console.log(pokemon.id) // unique numbers are here
return <Card key={i} pokemon={pokemon} />
})}
</div>
Equally, check this segment of card components.
{
pokemon.types.map((type,i) => {
return (
<div key={i} className="card__type" style={{backgroundColor:
typeColors[type.type.name]}}>
{type.type.name}
/div>
)
})
}
And
<div className="card__data card__data--ability">
<p className="title">Abilities:</p>
{/* {console.log(pokemon.abilities)} }
{pokemon.abilities.map((ability, i) => <p key={i}>{ability.ability.name}
</p>
)}
</div>
Previous answer will solve your problem. However, for your info, I would also like to add here.
For React a key attribute is like an identity of a node/element/tag which helps React to identify each item in the list and apply reconciliation correctlyon each item. Without a key React will render your component but may cause issue when you re-order your list.
React recommends to use id of the data instead of index number. However, if your list does not re-orders/ sorts or do not have id then you can use index.
You can read more here:
https://reactjs.org/docs/lists-and-keys.html
Change this:
<div className="card__types">
{
pokemon.types.map(type => {
return (
<div className="card__type"
style={{backgroundColor:typeColors[type.type.name]}}
>
{type.type.name}
</div>
)
})
}
</div>
to:
<div className="card__types">
{
pokemon.types.map((type, key) => {
return (
<div key={key} className="card__type"
style={{backgroundColor:typeColors[type.type.name]}}
>
{type.type.name}
</div>
)
})
}
</div>
and:
{pokemon.abilities.map(ability => <p>{ability.ability.name}</p>
to:
{pokemon.abilities.map((ability,key) => <p key={key} >{ability.ability.name}</p>

TypeError: Cannot read property '0' of null, react-fullpage

<div className="left">
<ReactFullpage
licenseKey='xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx'
sectionsColor={["#000000"]}
render={({ state, fullpageApi }) => {
return (
<div id="fullpage-wrapper">
{this.state.items == undefined ? '' : this.state.items.map((img,i) => (
<img className="section" key={i} src={img.image}></img>
))}
</div>
);
}}
/>
</div>
Hi, I've some issues when I am trying to fetch the data and render in ReactFullpage Component, the error says:
TypeError: Cannot read property '0' of null
Thank you, all help is welcome.
The issue here is that ReactFullPage works on the principle of finding a className section in one of the rendered elements
Now since you load your items async, initially the following content is rendered
return (
<div id="fullpage-wrapper">
{''}
</div>
);
Notice that it doesn't have a className section to it and it throws you the error
The solution here is to either wait for items to load before showing ReactFullPage
<div className="left">
{this.state.items && <ReactFullpage
licenseKey='xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx'
sectionsColor={["#000000"]}
render={({ state, fullpageApi }) => {
return (
<div id="fullpage-wrapper">
{this.state.items.map((img,i) => (
<img className="section" key={i} src={img.image}></img>
)}
</div>
);
}}
/>}
</div>
or return a dummy component to ReactFullPage
<div className="left">
<ReactFullpage
licenseKey='xxxxxxxx-xxxxxxxx-xxxxxxxx-xxxxxxxx'
sectionsColor={["#000000"]}
render={({ state, fullpageApi }) => {
return (
<div id="fullpage-wrapper">
{this.state.items == undefined ? <div className="section" /> : this.state.items.map((img,i) => (
<img className="section" key={i} src={img.image}></img>
))}
</div>
);
}}
/>
</div>

Cannot Render Nested Maps In ReactJS

I am trying to nest maps to render an array within an object
My Cards Component Render Method (Not Nested, Working):
render() {
return (
<div class="mediator-container">
{this.state.routeList.map(
(route, index) =>
<Card busName={this.state.routeList[index].$.tag} />
)}
<span class="loader">
<span class="loader-inner"></span>
</span>
</div>
);
}
My Cards Component Render Method (Nesteing, Not Working!!):
render() {
return (
<div class="mediator-container">
{this.state.routeList.map((route, index) =>
{
{
this.busTitleToDirectionName(this.state.routeList[index].$.tag).map(busDir => {
<Card busName={busDir} />;
});
}
}
)}
<span class="loader">
<span class="loader-inner"></span>
</span>
</div>
);
}
busTitleToDirectionName(int) returns an array of Strings
My Card Subcomponent's render method:
render() {
// Logging to see if render method is called
console.log("Ran");
return (
<div className="card">
<div className="card-header">
<div className="bus-name">
<p>{this.props.busName}</p>
</div>
</div>
</div>
);
}
How it looks like without nesting when it does work (Not enough reputation to post images so here are the links):
https://i.gyazo.com/66414925d60701a316b9f6325c834c12.png
I also log in the Card subcomponent so that we know that the Card component was ran and it logs that it did get called without nesting
https://i.gyazo.com/fb136e555bb3df7497fe9894273bf4d3.png
When nesting, nothing renders and the Card subcomponent isn't being called as there is no logging of it
https://i.gyazo.com/38df248525863b1cf5077d4064b0a15c.png
https://i.gyazo.com/d6bb4fb413dfc9f683b44c88cce04b8a.png
You can try below code in your nested case. In the nesting of map you have to wrap your nested map within a container. Here I use React.Fragment (<> ) as a container.
return (
<div class="mediator-container">
{this.state.routeList.map((route, index) =>
<>
{
this.busTitleToDirectionName(this.state.routeList[index].$.tag).map(busDir => {
<Card busName={busDir} />;
});
}
</>
)}
<span class="loader">
<span class="loader-inner"></span>
</span>
</div>
);
Hope it will help you!!
Thanks, Prahbat Kumar, but I figured out the issue. I had to return the subcomponent from the nested map here is the code:
render() {
return (
<div class="mediator-container">
{this.state.routeList.map((route, index) =>
this.busTitleToDirectionName(this.state.routeList[index].$.tag).map(busDir => {
return <Card busName={busDir} />
})
)}
<span class="loader">
<span class="loader-inner"></span>
</span>
</div>
);
}

Error while passing props: Uncaught TypeError: billingItem.map is not a function

I have this child component:
const TableExpandedRowItem = ({ dataTitle, rowValue, cellClassProp }) => (
<div data-title={dataTitle} className={cellClassProp}>
<p>{rowValue}</p>
</div>
);
I am passing it to its parent to create an iteration:
const TableExpandedRowWrapper = ({ rowClassProp, billingItem }) => (
<div className={rowClassProp}>
{billingItem.map(key => (
<div>
<TableExpandedRowItem
dataTitle={billingItem[key].description}
rowValue={billingItem[key].description}
/>
<TableExpandedRowItem
dataTitle={billingItem[key].recurringFee}
rowValue={billingItem[key].recurringFee}
/>
</div>
))}
</div>
);
I get this error:
Uncaught TypeError: billingItem.map is not a function
Here is where I need to call it:
{rowExpanded.billingItems &&
rowExpanded.billingItems.map(item =>
rowExpanded.id === item.cancellationRequestId && (
<div className="row" key={item.id}>
// HERE
<TableExpandedRowWrapper billingItem={item.billingItem} />
...
UPDATE:
If I call the component TableExpandedRowItem directly without a the wrapper component it works as it should:
{rowExpanded.billingItems &&
rowExpanded.billingItems.map(item =>
rowExpanded.id === item.cancellationRequestId && (
<div className="row" key={item.id}>
<TableExpandedRowItem
dataTitle={item.billingItem.description}
rowValue={item.billingItem.description}
/>
<TableExpandedRowItem
dataTitle={item.billingItem.recurringFee}
rowValue={item.billingItem.recurringFee}
/>
</div>
),
)}
I want to take this to another component which is what I am attempting to do on TableExpandedRowWrapper:
<div className="row" key={item.id}>
<TableExpandedRowItem
dataTitle={item.billingItem.description}
rowValue={item.billingItem.description}
/>
<TableExpandedRowItem
dataTitle={item.billingItem.recurringFee}
rowValue={item.billingItem.recurringFee}
/>
</div>
So basically what I need is to put TableExpandedRowItem into a wrapper and call it as shown above.

Categories

Resources