Check if index of iteration is divisible by 2 - javascript

I know I can check this with pure Js index % 2 === 0 however when
I'm attempting to use it in React which should work I get errors from linter:
<div className="columns">
{posts.map((item,index) => (
<>
<div className="column is-half">
<Card {...item} />
</div>
{index % 2 === 0 && </div><div className="columns">}
</>
))}
What am I doing wrong ?
Edit:
<div className="columns">
{posts.map((item,index) => (
<div className="column is-half">
<Card {...item} />
</div>
{index % 2 === 0 && (
</div><div className="columns">
)}
))}
The above still throws syntax error. I've checked brackets and logic is correct too.

I think you have invalid JSX syntax and this is your issue.
You cannot open a div element without setting the closing tag directly or setting the closing tag in a loop. This is invalid syntax, even if it would fit from the logic...
Try this:
<div className="columns">
{
posts.map((item,index) => (
<>
<div className="column is-half">
<Card {...item} />
</div>
{
index % 2 === 0 &&
<div className="columns">
</div>
}
</>
))
}
</div>

Related

Search input loses focus when it doesn't find any title

Whenever I try to search, I can type only the letters which are similar to the one of the titles. If any letter is different I lose focus from input. It used to work normally before, but Idk what happened now. Any suggestions?
How it first looks like:
After starting to type on search input:
When I type a letter which is not in the title:
Code:
if (props.items.length === 0) {
return (
<div className="files-list center">
<Card>
<h2>No files found.</h2>
</Card>
</div>
);
} else if (
props.items.filter(
(file) =>
file.title.toLowerCase().includes(searchInput) ||
file.title.toUpperCase().includes(searchInput)
).length === 0
) {
return (
<div className="filesList">
<div className="search">
<input
type="text"
placeholder="Search Files"
onChange={(event) => setSearchInput(event.target.value)}
/>
</div>
<Card>
<h2>No files found.</h2>
</Card>
</div>
);
}
return (
<React.Fragment>
<div className="filesList">
<div className="actionsBtn">
<NavLink to="/add-file" className="addFileBtn" title="Add File">
<FontAwesomeIcon icon={faPlus} />
</NavLink>
<input
type="text"
placeholder="Search Files"
onChange={(event) => setSearchInput(event.target.value)}
/>
</div>
<ul className="files-list">
{props.items
.filter(
(file) =>
file.title.toLowerCase().includes(searchInput) ||
file.title.toUpperCase().includes(searchInput)
)
.map((file) => (
<FilesPostItem
key={file.id}
id={file.id}
title={file.title}
file={file.file}
creator={file.creator.name}
description={file.description}
creatorId={file.creator}
onDelete={props.onDeleteFile}
/>
))}
</ul>
</div>
</React.Fragment>
);
What I think happens is, your “default” return form the beginning gets reset by the return in the “if else”. So the Input is a new DOM Element and loses focus.
You might want to add something like this to your default return and remove your "if else" statement.
<ul className="files-list">
{props.items
.filter(
(file) =>
file.title.toLowerCase().includes(searchInput) ||
file.title.toUpperCase().includes(searchInput)
)
.map((file) => (
<FilesPostItem
key={file.id}
id={file.id}
title={file.title}
file={file.file}
creator={file.creator.name}
description={file.description}
creatorId={file.creator}
onDelete={props.onDeleteFile}
/>
))}
</ul>
{props.items
.filter(
(file) =>
file.title.toLowerCase().includes(searchInput) ||
file.title.toUpperCase().includes(searchInput)
).length > 0 &&
<Card>
<h2>No files found.</h2>
</Card>
}
What does this do?
It adds the "No files found" message to your default return and shows it only, if items is empty.
But i am pretty sure, there is a better way to do this.

React, conditional rendering inside map method

I have the following code and I want to apply a conditional rendering, because the index 0 does not exist. I don't want to render the information for this particular index. How can I do it?
return (
<section>
{pokemonCards.map((pokemon, index) =>
<div key={index}>
<img
src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${index}.png`}
alt={pokemon.name}/>
<p>{pokemon.name}</p>
</div>
)}
<button
className="get-more-button"
onClick={getMorePokemons}>Get more pokemons
</button>
</section>
)
This should work:
return (
<section>
{pokemonCards.map((pokemon, index) =>
{index === 0 ? null : <div key={index}>
<img
src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${index}.png`}
alt={pokemon.name}/>
<p>{pokemon.name}</p>
</div>
)}
<button
className="get-more-button"
onClick={getMorePokemons}>Get more pokemons
</button>}
</section>
)
You could do as below if you do not want to render an empty div for the nonexisting pokemon:
return (
<section>
{pokemonCards.map(
(pokemon, index) =>
index !== 0 && (
<div key={index}>
<img
src={`https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/${index}.png`}
alt={pokemon.name}
/>
<p>{pokemon.name}</p>
</div>
)
)}
<button className="get-more-button" onClick={getMorePokemons}>
Get more pokemons
</button>
</section>
);

React Nested Foreach on Return

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

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>

React map - don't return item if missing

I'm using map in react to show a feed of facebook posts, but i don't want the post to render if the message field is missing from the json data.
If I do this I get an error ('if' is an unexpected token) and my project won't build
return (
<Slider
{...Settings}>
{postsAvailable && posts.map((post, index) => (
if (!post.message) return null
return (<div key={post.id}>
{ index === 0 && <Item /> }
{ index > 0 && <div className='item'>
<img data-original={post.full_picture} className='img-responsive' />
<div className={`facebook-content slide-${post.id}`}>
<p className='text'>{post.message}</p>
</div>
</div> }
</div>)
))}
</Slider>
)
You can use filter first:
posts.filter((post) => post.message).map((post, index) => (...
Although, if possible you should filter when you get the posts, and not in the render function. Do as little as possible in the render function - for a good overview, and for performance.
You are not giving your function given to map a body. Change () to {} and it will work as expected.
return (
<Slider {...Settings}>
{postsAvailable &&
posts.map((post, index) => {
if (!post.message) return null;
return (
<div key={post.id}>
{index === 0 && <Item />}
{index > 0 && (
<div className="item">
<img
data-original={post.full_picture}
className="img-responsive"
/>
<div className={`facebook-content slide-${post.id}`}>
<p className="text">{post.message}</p>
</div>
</div>
)}
</div>
);
})}
</Slider>
);
Alternatively you could filter out all the posts that don't have a message first and then map those that does.
return (
<Slider {...Settings}>
{postsAvailable &&
posts
.filter(post => post.message)
.map((post, index) => (
<div key={post.id}>
{index === 0 && <Item />}
{index > 0 && (
<div className="item">
<img
data-original={post.full_picture}
className="img-responsive"
/>
<div className={`facebook-content slide-${post.id}`}>
<p className="text">{post.message}</p>
</div>
</div>
)}
</div>
))}
</Slider>
);

Categories

Resources