Filter condition in Reactjs - javascript

I'm trying to execute if the table has data or not. If there's data only that table will show the other will stay on no records found and vice versa. I feel like I'm wrong about my condition.
render() {
const { legal_records } = this.props;
return (
<div className="row">
<div className="col">
<div className="card">
<div className="card-body">
{legal_records.size ? (
<div
className="table-responsive"
style={{ overflowX: "hidden", maxHeight: 600 }}
>
<LegalService
data={legal_records}
onSettle={this.onSettle}
/>
</div>
) : (
<div className="no-content text-center my-3">
<i className="material-icons">find_in_page</i>
<h6 className="text-muted">No Record Found</h6>
</div>
)}
</div>
<div className="card-body">
{legal_records.size ? (
<div
className="table-responsive"
style={{ overflowX: "hidden", maxHeight: 600 }}
>
<LegalDivision
data={legal_records}
onSelectPay={this.onSelectPay}
/>
</div>
) : (
<div className="no-content text-center my-3">
<i className="material-icons">find_in_page</i>
<h6 className="text-muted">No Record Found</h6>
</div>
)}
</div>
</div>
</div>
</div>
);
}
}

If legal_records is an array, you need to access .length instead:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length
change the condition to:
legal_records.length > 0

Assuming that legal_records is an array:
legal_records.size should be legal_records.length
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/length

Assuming that legal_records is an object you could do something like this:
Object.entries(legal_records).length > 0
Which will determine whether or not an object has any items in it.
See the docs on Object.entries(...) here.
Though, without knowing the type of legal_records it's hard to give an appropriate answer.

Related

how to not display an element if it is undefined react

There is the following problem. I have 6 divs on the page, which may or may not contain an image. Let's say I have 3 pictures in the array and these pictures should be displayed in a div, and the remaining 3 elements should be a div (for example, with a background) I roughly solved it, but if this element is not found in the array, then the application crashes. Crashing because some element is missing. In the console, an error like sixb[3] is undefined.
Item Display
<div className='blocksix all'>
<img src={sixb[0].img} />
</div>
<div className='blocksix all'>
<img src={sixb[1].img} />
</div>
<div className='blocksix all'>
<img src={sixb[2].img} />
</div>
<div className='blocksix all'>
<img src={sixb[3].img} />
</div>
<div className='blocksix all'>
<img src={sixb[4].img} />
</div>
<div className='blocksix all'>
<img src={sixb[5].img} />
</div>
Array of elements
let [sixb , setsixb] = useState([
{img:"https://www.zonkpro.ru/zonk/assets/dice/mini/1.png"},
{id:2,title:2, img:"https://www.zonkpro.ru/zonk/assets/dice/mini/2.png" , style: 'none'},
{id:3,title:3, img:"https://www.zonkpro.ru/zonk/assets/dice/mini/3.png" , style: 'none'},
{id:4,title:4, img:"https://www.zonkpro.ru/zonk/assets/dice/mini/4.png" , style: 'none'},
{id:5,title:5, img:"https://www.zonkpro.ru/zonk/assets/dice/mini/5.png" , style: 'none'},
{id:6,title:6, img:"https://www.zonkpro.ru/zonk/assets/dice/mini/6.png" , style: 'none'},
])
No ideas yet how to solve
Try ternary operator and optional chaining
<div className='blocksix all'>
{sixb?.[1]?.img ? <img src={sixb[1].img} /> : <div className='some-background'>No image</div>}
</div>
Generic way of doing it -
{setsixb.map((item, index)=>{
retrun <div className='blocksix all' key={index}>
{item?.img ? <img src={item.img} /> : <div className='some-background'>No image</div>}
</div>
})
}
You can use conditional rendering in this scenario.
<div className='blocksix all'>
{sixb[0] && sixb[0].img && (<img src={sixb[0].img} />)}
</div>
Note:- Instead of writing the same div 6 times, just iterate over the array and display them.
{
sixb.map((each,index) => {
return (
<div key={index} className='blocksix all'>
{each && each.img && (<img src={each.img} />)}
</div>
)
})
}
For key, I have used index as you don't have any unique property in an object. If you can make the id mandatory then use id as the key.
This way the code is more clean and readable.
You should try this,
<>
{sixb.map((element, index) => element?.img ? <div key={index} className="block-image"><img src="img" /></div> : <div key={index} className="no-image">No Image found</div>)}
</>

React Server-side rendering error due to mismatch between client and server

I am working on a React app (18.2.0 version to be exact), which uses server side rendering. On one of the pages, I am getting a following error:
Code of the component:
<div className="O111-color-module O111-color-module--multi container is-opened" suppressHydrationWarning={true}>
<div className="O111-color-module-filters container">
{colorsData.colorFilters.map((filter, index) => <div key={index} className="O111-color-module-card offset-383">
<h2 className="O111-color-module-filters__header">{props.header}</h2>
<BaseSelect handleChange={handleFilterChange} selectedValue={selectedFilterGroup} options={getColorGroupOptions(filter)} label={filter.label} />
</div>)}
</div>
<div className="card-list--swipe-stack-cards">
<div className={`card details ${mobileFullScreenDetails && 'O111-color-module--multi-details-block'}`}>
<div className="O111-color-module--multi-details has-value">
<div className="O111-color-module--multi-details-top">
<div className={`O111-color-module--multi-details-top is-${selectedColor.colorType}`}>
<div className="O111-color-module--multi-details-color"
style={{ backgroundImage: `url('${selectedColor.previewColorImage}')` }}>
<h3>{selectedColor.colorName}</h3> {/*<---This is where the error is being thrown*/}
</div>
<div className="O111-color-module--multi-details-info">
<ColorProperties {...props} color={selectedColor} />
</div>
<button className="modal__close js-modal__close" onClick={() => setMobileFulscreenDetails(false)} />
{selectedColor.matchingColors && selectedColor.matchingColors.length > 0 &&
<div className="O111-color-module--multi-details-matching-colors">
<h4>{props.matchingColorsLabel}</h4>
<div className="O111-color-module--multi-details-matching-colors-container">
{selectedColor.matchingColors.map((matchingColor, index) =>
<div key={index}
className={`is-${matchingColor.colorType}`}
onClick={() => handleColorSelection(matchingColor.id)}
style={{ backgroundImage: `url('${matchingColor.colorImage}')` }}>
<span> {matchingColor.colorCode} </span>
</div>
)}
</div>
</div>}
</div>
</div>
<div className="O111-color-module--multi-details-bottom">
{getColorSampleOrder()}
</div>
</div>
</div>
</div>
I have added the suppressHydrationWarning={true} prop to the most outer div in the component, but it didn't make the error go away.
Anybody knows what exactly is causing the problem and why is there mismatch between client and server? I am not using Next.js (most questions with SSR-related problems in React are in apps which are using it).

Conditional styling in react map

I only want to show the display block on the hovered item. but when I hover it shows on every item in a map function. what I'm doing wrong.
basically, I just want to show hovered movie item's title. for now, it shows every movie when I hover.
MovieList.js
const [popular, setPopular] = useState([]);
const [hover, setHover] = useState(false);
return (
<>
<div className="movie-list">
<h2 style={{ fontSize: "49px", marginLeft: "60px" }}>What's Popular</h2>
<div className="popular">
{popular.map((pop, index) => (
<>
<div className="movie" key={index}>
<div className="tot" onMouseEnter={() => setHover(true)}>
<h4
id="pop-title"
style={{ display: hover ? "block" : "none" }}
key={index}
>
{pop.title}
</h4>
</div>
<img
src={"https://image.tmdb.org/t/p/w500" + pop.poster_path}
id="movie-img"
/>
</div>
</>
))}
</div>
</div>
</>
);
};
export default MovieList;
The same hover state variable is used for all your movies, so when it becomes true, all the movies are affected by the change. You could use something like an object instead of just a boolean to store one hover state per movie.
Another problem with your code that isn't helping:
You are missing a unique key prop on each item of the map (it must be on the direct child).
Solution 1: Remove the Fragment
Everything is already under one div so you don't need the React Fragment (<>) in that case. Also, you might wanna use something unique to the current map item other than the index in the array.
{popular.map((pop) => (
<div className="movie" key={pop.somethingUnique}>
<div className="tot" onMouseEnter={() => setHover(true)}>
<h4 id="pop-title" style={{ display: hover ? "block" : "none" }}>
{pop.title}
</h4>
</div>
<img
src={"https://image.tmdb.org/t/p/w500" + pop.poster_path}
id="movie-img"
/>
</div>
))}
Solution 2: Set the key on the Fragment
{popular.map((pop) => (
<Fragment key={pop.somethingUnique}>
<div className="movie">
<div className="tot" onMouseEnter={() => setHover(true)}>
<h4 id="pop-title" style={{ display: hover ? "block" : "none" }}>
{pop.title}
</h4>
</div>
<img
src={"https://image.tmdb.org/t/p/w500" + pop.poster_path}
id="movie-img"
/>
</div>
</Fragment>
))}

Having a loop to change the style of a card after every interval

Currently I have a container that holds my images in a particular pattern where the 1st and 6th card are horizontally elongated and cards 2 to 5 are vertically elongated. As of now all these images are hardcoded, but I want to have a .map function that will take the data from my backend. But the problem is .map takes 1 layout and duplicates it, but I want it to follow my particular pattern for which I assume I would need a loop.
CodeSandbox: https://codesandbox.io/s/gallant-forest-vygnw?file=/src/App.js
Code:
<div className="container">
<div className="row">
{/* {posts &&
posts.map((item) => ( */}
<div className="col-md-6 col-sm-6">
<div className="row">
<div className="col-md-12">
<img src="https://c2.staticflickr.com/9/8817/28973449265_07e3aa5d2e_b.jpg" />
</div>
</div>
<div className="row">
<div className="col-md-6 col-sm-6">
<img
style={{ minHeight: "280px", objectFit: "cover" }}
src="https://c2.staticflickr.com/9/8817/28973449265_07e3aa5d2e_b.jpg"
/>
</div>
<div className="col-md-6 col-sm-6">
<img
style={{ minHeight: "280px", objectFit: "cover" }}
src="https://c2.staticflickr.com/9/8817/28973449265_07e3aa5d2e_b.jpg"
/>
</div>
</div>
</div>
<div className="col-md-6 col-sm-6">
<div className="row">
<div className="col-md-6 col-sm-6">
<img
style={{ minHeight: "280px", objectFit: "cover" }}
src="https://c2.staticflickr.com/9/8817/28973449265_07e3aa5d2e_b.jpg"
/>
</div>
<div className="col-md-6 col-sm-6">
<img
style={{ minHeight: "280px", objectFit: "cover" }}
src="https://c2.staticflickr.com/9/8817/28973449265_07e3aa5d2e_b.jpg"
/>
</div>
</div>
<div className="row">
<div className="col-md-12">
<img src="https://c2.staticflickr.com/9/8817/28973449265_07e3aa5d2e_b.jpg" />
</div>
</div>
</div>
{/* ))} */}
</div>
</div>
try using index in map to customize how you want it.
posts.map((item, idx) => (
<div className={idx === 0 ? "col-md-12" : "col-md-6 col-sm-6"}>
<img
src={item?.src}
alt={item?.caption}
style={{ minHeight: "280px", objectFit: "cover" }}
/>
</div>
Codesandbox
https://codesandbox.io/s/sad-shannon-wkc28?file=/src/App.js
I'm not use to help on this site but i maybe have an answer for you.
It seems your 'posts' only have 3 items so mapping on this wont make you have the 6 images you need. Whatever, you said the datas have to come frome your backend so i presume it's just some testing data.
I suggest you to use .map normally but define the differences with CSS. Then you can easily select the first and the last element of your mapping with something like that :
container div:first-child div:first-child, container div:last-child div:last-child{
//your css
}
But as you using bootsrap for styling, you need to translate the bootstrap classes for this method. I suggest you an other. The .map function can get an index as second argument. So you can do something like this :
posts.map(element, i => {yourcode} )
Then use the index for knowing if it is the first or the last item in a ternary expression :
i === 0 || i === posts.length ? your code for the first and last : normal code for the others
EDIT:
I've try in the sandbox, it seems the problem with your patern is that every elements are not independents. The div element who appears every 3 items screw up everything for using map. My best result was this :
return (
<div className="App">
<div className="container">
<div className="row">
{posts &&
posts.map((item, i) => {
return (i+1)%4 === 0 || i===0 ?
(
<div className="col-md-6 col-sm-6">
<div className="row">
<div className={ i === 0 || i === (posts.length-1) ? "col-md-12" : "col-md-6 col-sm-6"}>
<img src="https://c2.staticflickr.com/9/8817/28973449265_07e3aa5d2e_b.jpg" />
</div>
</div>
</div>
)
:
(
<div className="row">
<div className={ i === 0 || i === (posts.length-1) ? "col-md-12" : "col-md-6 col-sm-6"}>
<img src="https://c2.staticflickr.com/9/8817/28973449265_07e3aa5d2e_b.jpg" />
</div>
</div>)
})}
</div>
</div>
</div>
);
But i can't figuring out how handle this parent div for encapsulating every 3 element. Here a suggestion that i've not trying yet :
Create a component who will mapping inside the problematic div.
Find a way to create a 2D Array with your request, each Array in this one composed by 3 elements
Mapping the 2D Array using your component.
The first mapping will map over each Array in your 2D array and the second map, inside your component, will map over the elements.

Can't access nested Objects JSON in React JSX

I can access JSON objects in the results here
useEffect(() => {
fetch(`/user/${userid}`,{
method:'get',
headers:{
"Authorization":`Bearer ${localStorage.getItem('token')}`}
}).then(res=>res.json())
.then(result=>{
console.log(result.user.name) //I can access JSON objects in the results here//
setProfile(result)
})
.catch(err=>console.log(err))
}, [])
I can access JSON while Changing State but it throws errors like UserProfile.user is undefined,UserProfile.posts.length is undefined when rendering JSX. TO access the nested Data I have tried creating more state Variables. It works but the code have become long. I looked for solution in various website but could not find. Any one help me.
return (
<>
{
UserProfile?<div style={{maxWidth:'800px',margin:"0px auto"}}>
<div style={{
display:"flex",
justifyContent:'space-around',
margin:"18px 0px"
}}>
<div>
<img style={{borderBottom:"1px solid grey",width:"160px",height:"160px",borderRadius:"80px"}} src="https://images.unsplash.com/photo-1569466896818-335b1bedfcce?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60"/>
</div>
<div>
<h4>{UserProfile?UserProfile.user.name:"Loading..."}</h4>
<div style={{display:"flex",justifyContent:"space-between",width:"100%"}}>
<h6>{UserProfile.posts.length} posts </h6>
<button onClick={()=>followUser()} className="btn waves-effect waves-light #64b5f6 blue lighten-2" type="button" name="action">Follow</button>
</div>
</div>
</div>
<div className="gallery">
{
UserProfile.posts.map((item)=>{
return(
<img className="item" key={item._id} src={item.photo}/>
)
})
}
</div>
</div>:
<h1>Loading:</h1>
}
</>
)
export default Profile
Based on the code and your inputs, the problem may be because you are trying to access the variables before they are accessible.
As you are making async API call in useEffect() it may take some time before you get data. But, as you are accessing the data before you even get it errors like 'UserProfile.user is undefined', 'UserProfile.posts.length' is undefined will occur'
To avoid such errors make sure you add a check as shown below
<>
{
UserProfile &&
<div style={{maxWidth:'800px',margin:"0px auto"}}>
<div style={{
display:"flex",
justifyContent:'space-around',
margin:"18px 0px"
}}>
<div>
<img style={{borderBottom:"1px solid grey",width:"160px",height:"160px",borderRadius:"80px"}} src="https://images.unsplash.com/photo-1569466896818-335b1bedfcce?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60"/>
</div>
<div>
/* -----> modify it here*/ <h4>{UserProfile ? UserProfile.user && UserProfile.user.name:"Loading..."}</h4>
<div style={{display:"flex",justifyContent:"space-between",width:"100%"}}>
/* -----> modify it here*/ <h6>{UserProfile && UserProfile.posts && UserProfile.posts.length} posts </h6>
<button onClick={()=>followUser()} className="btn waves-effect waves-light #64b5f6 blue lighten-2" type="button" name="action">Follow</button>
</div>
</div>
</div>
<div className="gallery">
{
UserProfile.posts.map((item)=>{
return(
<img className="item" key={item._id} src={item.photo}/>
)
})
}
</div>
</div>
:
<h1>Loading:</h1>
}
</>
I got the solution for this. I got rid of this problem by setting initial state to null. Thank You for answering my query.
//my initial useState declaration//
const [userProfile,setUserProfile]=useState([])
//Solution//
const [userProfile,setUserProfile]=useState(null)
I am new to react so I got into problem.

Categories

Resources