Ternary operator is not working in react js render function - javascript

We have a simple return render operation and we are deceding the return html using ternary operator, on the basis of state variable(anyException) value. Code snippet is shown below :
return <Form
validate={ formValidation }
onSubmit={this.onSubmit}
initialValues={initialValues}
render={({ handleSubmit, submitting, valid }) => (<form onSubmit={handleSubmit} className="k-form">
<div className="container-fixed">
(this.state.anyException ?
<ErrorDialogPopup
anyException={this.state.anyException}
errorInfo={this.state.errorInfo}
toggleErrorDialog={this.toggleErrorDialog.bind(this)}
/> : <div className="row">
{this.state.errorMessages.map(function(errorMessage) {
return <div className="errorMessage">{errorMessage}</div>
})}
</div>)
<div>
<div className="row">
<div className="col-sm-12">
<div className="panel panel-default" id="frmNetworkAdd">
<div className="panel-heading">
<h1 className="panel-title" id="panelHeader">
{this.state.networkId === -1? <span>Add Network</span> : <span>Edit Network</span>}
</h1>
</div>
But during run time, both the cases getting displayed. Could you please suggest what is going wrong here.

Instead of wrapping your ternary in (), use {} instead.
<div className="container-fixed">
{this.state.anyException ?
<ErrorDialogPopup
anyException={this.state.anyException}
errorInfo={this.state.errorInfo}
toggleErrorDialog={this.toggleErrorDialog.bind(this)}
/> : <div className="row">
{this.state.errorMessages.map(function(errorMessage) {
return <div className="errorMessage">{errorMessage}</div>
})}
</div>
}
</div>

Related

If - else statement not appropriately working in ReactJS

I am displaying some data from an api using the If - else condition whereby the data should be loaded, and if nothing is found, a No data Found text should be displayed
But the problem is, the No Data Found text displays immediately the page is opened. It doesn't wait for the whole data from the api to load to appear. And when the data is loaded is when it disappears or stays if the data is not there.
How do I make the No Data Found text appear only after the data is loaded and verified to be null. Thanks.
Here is my code...
var showFarmList = '';
if (farmCount >= 1) {
showFarmList = user.farm.map((farm) => {
return (
<div className="col-6" key={farm.farmid}>
<div className="card card-dull card-height">
<Link to={`/farm-details/${user.username}/${farm.farmid}`}>
<div className="card-body">
<div className="farms-card">
<h5 className="card-title title-small truncate-1">{farm.farmname}</h5>
</div>
<p className="card-text truncate-3">{farm.county.countydescription}
</p>
</div>
</Link>
</div>
</div>
)
});
}
else {
showFarmList =
<>
<div className='row'>
No Data Found
</div>
</>
}
return (
<>
<div className="appHeader no-border transparent position-absolute">
<div className="left">
<a onClick={() => navigate(-1)} className="headerButton goBack">
<i className="fi fi-rr-cross"></i> </a>
</div>
<div className="pageTitle"></div>
</div>
<div id="appCapsule" className="mt-2">
<div className="section my-farmlist">
<h2>My Farms</h2>
<p className="my-farmtext">Here is a list of all the Farms you have registered on Tunda Care</p>
<div className="row">
{isLoading && <CardSkeleton cards={2} />}
{showFarmList}
</div>
</div>
</div>
</>
);
}
export default MyFarmList;
And here is the output.
I think this is what you expecting if I understood correctly.
Add !isLoading && to second part.
<div className="row">
{isLoading && <CardSkeleton cards={2} />}
{!isLoading && showFarmList}
</div>

hide a div in react when there is no anchor tag in it

I have a react code (just a snippet, its not a complete code) as shown below which shows the list of programs on the webpage. Line A in the react code below renders all list of program on the webpage.
react code:
const renderPrograms = () => {
return programs.map((program, index)=>{
return (
<a href={program.url} key={index}>
<div className="program" >
<div class="hello-world">{program.name}</div>
</div >
</a>
)
})
}
return(
<div class="parent-div">
<div className ="pqr-xyz">
<h5>Hello World</h5>
</div>
<div className ="abc-def">
<h5>Programs</h5>
{programs && renderPrograms()} {/*Line A*/}
</div>
</div>
)
The above react code renders the following html code at runtime:
<div class="parent-div">
<div className ="pqr-xyz">
<h5>Hello World</h5>
</div>
<div class="abc-def">
<h5>Programs</h5>
<a href="https://www.google.com/">
<div class="program">
<div class="hello-world">TYUV</div>
</div>
</a>
<a href="https://www.twitter.com/">
<div class="program">
<div class="hello-world">SGHS</div>
</div>
</a>
</div>
</div>
Problem Statement:
When Line A does not render anything, my div (<div className ="abc-def">) will look like this at run time:
<div class="abc-def">
<h5>Programs</h5>
</div>
I am wondering what changes I need to make in my react code above so that when Line A doesn't render anything then <div class="abc-def"><h5>Programs</h5></div> should not display on the webpage.
They should be part of the condition:
return(
programs.length > 0 && <div className ="abc-def">
<h5>Programs</h5>
{renderPrograms()}
</div>
)
I changed the condition to check for length, otherwise you'll get a 0 instead of nothing, when empty
Try change this lines:
<div className ="abc-def">
<h5>Programs</h5>
{programs && renderPrograms()} {/*Line A*/}
</div>
into this:
{ programs && (
<div className ="abc-def">
<h5>Programs</h5>
{renderPrograms()} {/*Line A*/}
</div>
) }
Now without programs nothing is displayed.
You can try adding a className like this:
<div className={`abc-def ${programs.length ? "hidden" : ""}`}
Or from the parent componet, you can choose to not render this component with <div>
Instead of trying to hide it using CSS, you also can choose to not render it at all by returning nothing from your function
const RenderPrograms = ({ programs = [] }) => {
if (!programs.length) {
return []
}
return (
<div className="abc-def">
<h5>Programs</h5>
{programs.map((program, index) =>
<a href={program.url} key={index}>
<div className="program">
<div>{program.name}</div>
</div>
</a>
)}
</div>
)
}
ReactDOM.render(
<RenderPrograms />,
document.getElementById('react')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
You can try putting your class in a template string and using a ternary operator to display a certain class when some state value is true.
<div className={`${stateValue ? "name-of-class-with-hide" : "abc-def"}`}>
Here is a complete solution. All you need to do is move the <h5>Programs</h5> inside the condition and modify the condition slightly as shown in following snippet.
<div className ="abc-def">
{
programs.length > 0 && (
<div>
<h5>Programs</h5>
<RenderPrograms programs = {programs}/>
</div>
)
}
</div>
Note that I have modified the RenderPrograms function as well to accept arguments.
Following is a full snippet.
function RenderPrograms(props) {
return props.programs.map((program, index)=>{
return (
<a href={program.url} key={index}>
<div className="program" >
<div className="hello-world">{program.name}</div>
</div >
</a>
)
});
}
function MyApp() {
const programs=[
{name:'program 1', url: 'https://url1.com'},
{name:'program 2', url: 'url2'},
{name:'program 3', url: 'url3'},
];
const programs1 = []; // empty program list
return(
<div class="parent-div">
<h1>When programs list is not empty</h1>
{/*Above line is just for explanation -- you may remove it*/}
<div className ="pqr-xyz">
<h5>Hello World</h5>
</div>
<div className ="abc-def">
{
programs.length > 0 && (
<div>
<h5>Programs</h5>
<RenderPrograms programs = {programs}/>
</div>
)
}
</div>
{/*Below code is just for explanation -- you may remove it*/}
<hr />
<h1>When programs list is empty</h1>
<div className ="pqr-xyz">
<h5>Hello World</h5>
</div>
<div className ="abc-def">
{
programs1.length > 0 && (
<div>
<h5>Programs</h5>
<RenderPrograms programs = {programs1}/>
</div>
)
}
</div>
</div>
)
}
ReactDOM.render(
<MyApp />,
document.getElementById('app')
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
You need to move rendering of programs into RenderPrograms component. Make RenderPrograms component purelu functional and pass data to it via props (Instead of using function).
const RenderPrograms = ({ programs }) => {
let disp = programs.map((program, index) => {
return (
<a href={program.url} key={index}>
<div className="program">
<div class="hello-world">{program.name}</div>
</div>
</a>
);
});
return disp || <span />;
};
then use RenderPrograms to render programs in main component (One with logis for loading programs).
// let programs = [
// {
// url: "test1.com",
// name: "test1"
// },
// {
// url: "test2.com",
// name: "test2"
// }
// ];
let programs = [];
return (
<div className="App">
<div class="parent-div">
<div className="pqr-xyz">
<h5>Hello World</h5>
</div>
<div className="abc-def">
<h5>Programs</h5>
<RenderPrograms programs={programs} />
{/* {programs && renderPrograms()} Line A */}
</div>
</div>
</div>
);
You can play around with this sandbox

Typerror: object is not a function or its return value is not iterable in react 16.13.1

I am using react version 16.13.1. And i have used hooks alot of time in my project.but now am getting this error even before i use it.
export default function TourData(props) {
const [collapsed, setCollapsed] = useState();
const withinDatacollapse = props.tourWithin.slice(1);
const withinDatashow = props.tourWithin.slice(0, 1);
function handleViewAll() {
setCollapsed(!collapsed);
}
function Object(props) {
return (
<div>
{props.data &&
props.data.map((item, index) => (
<div key={index} className="within">
<div
className="image"
style={{ background: `url(${item.image})` }}
>
<div className="destination">{item.country}</div>
</div>
<div className="options">
<div>
<h5>Options</h5>
<div className="user-select">
<Select
options={item.options}
placeholder={<h4>Select Option</h4>}
/>
</div>
</div>
</div>
<div className="date-select">
<div className="user-select">
<Select
options={item.date_options}
placeholder={<h4>Select Date</h4>}
/>
</div>
</div>
<div>
<button>Go!</button>
</div>
</div>
))}
</div>
);
}
return (
<div className="route">
<div className="list-box">
<Object data={withinDatashow} />
<Collapse in={collapsed}>
<Object data={withinDatacollapse} />
</Collapse>
<div className="bottom-view-section">
<button onClick={handleViewAll}>View All</button>
</div>
</div>
</div>
);
}
Here i just declared the hook, and am getting this error.
I cant find where i have went wrong.
At first i had an error TypeError: Cannot read property 'map' of undefined where i do mapping , so i had to put props.data && just before the mapping.
You shouldn't name your components as Javascript's keywords like Object or class.
Also, you might want to define default value for props.placeData so when it is undefined, you don't get errors.
export default function AppMain({placeData = [], ...props}) {
Or you can just check in return, and say something like 'there is no place'. It's up to you.

Couldn't get rid of react warning of unique key in map

What's wrong with my below code? I had key={obj._id} and I expect I will not see the warning but I'm still getting it.
Warning: Each child in an array or iterator should have a unique "key"
prop. Check the render method..
renderListItems(items){
return(
<div>
{map(items, obj =>
<div key={obj._id} className="panel-body panel-row">
<div className="row">
<div className="col-md-12">
<h2 className="title">{obj.display_name}</h2>
<p className="edited">Last edited on {moment(obj.updated_at).format('DD MMM YYYY')}</p>
<div className="actions_wrap">
<Link to={`/mall-promospace/edit/${obj._id}`}>Edit</Link>
<a onClick={()=> this.setState({openConfirmationModal:true, selectedItemId: obj._id, selectedItemName: obj.display_name})}>Delete</a>
</div>
</div>
</div>
</div>
)}
</div>
)
}
I think you are coding some things wrong. You should apply the function "map" over an array.
Try this:
renderListItems(items){
return(
<div>
{items.map(obj =>
<div key={obj._id} className="panel-body panel-row">
<div className="row">
<div className="col-md-12">
<h2 className="title">{obj.display_name}</h2>
<p className="edited">Last edited on {moment(obj.updated_at).format('DD MMM YYYY')}</p>
<div className="actions_wrap">
<Link to={`/mall-promospace/edit/${obj._id}`}>Edit</Link>
<a onClick={()=> this.setState({openConfirmationModal:true, selectedItemId: obj._id, selectedItemName: obj.display_name})}>Delete</a>
</div>
</div>
</div>
</div>
)}
</div>
)
}
items.map((obj, i) => <div key={i}></div>)

React onClick handler in map function

I've been searching the web for answers to my question, but without success. I am trying to add a simple react click handler to my button, but I can't seem to make it work. It is probably something really simple, I just can't wrap my head around it.
Here is my code:
export default class ReviewBox extends Component {
deleteReview() {
console.log("hey");
}
render() {
const {reviews, date, lectureId} = this.props;
const that = this;
return (
<div className="container content-sm">
<div className="headline"><h2>Reviews</h2> <span>{date}</span></div>
<div className="row margin-bottom-20">
{reviews.map(review => {
return(
<div className="col-md-3 col-sm-6">
<div className="thumbnails thumbnail-style thumbnail-kenburn">
<div className="caption">
<h3>{review.comment}</h3> <br />
<button className="btn btn-danger" onClick={this.deleteReview()}>Delete</button>
</div>
</div>
</div>
)
})}
</div>
<hr />
<AddReview lectureId={lectureId} />
</div>
)
}
}
It refuses to fire the function when I click a button. I've tried with .bind(this) and onClick={() => this.deleteReview} etc.
All help appreciated!
I think you are missing braces () in arrow function
<button className="btn btn-danger" onClick={() => this.deleteReview()}>Delete</button>
i think this will help you.....
export default class ReviewBox extends Component {
deleteReview() {
console.log("hey");
},
render() {
const {reviews, date, lectureId} = this.props;
const that = this;
return (
<div className="container content-sm">
<div className="headline"><h2>Reviews</h2> <span>{date}</span></div>
<div className="row margin-bottom-20">
{reviews.map(review => {
return(
<div className="col-md-3 col-sm-6">
<div className="thumbnails thumbnail-style thumbnail-kenburn">
<div className="caption">
<h3>{review.comment}</h3> <br />
<button className="btn btn-danger" onClick={this.deleteReview}>Delete</button>
</div>
</div>
</div>
)
})}
</div>
<hr />
<AddReview lectureId={lectureId} />
</div>
)
}
}
Removing () from the onClick function call and using { this.deleteReview } will indeed fire up the method, but if you need to bind this as well inside that method, go with #duwalanise answer.
Ah, now I understand.
It is because I am rendering the react on serverside, that's why the click handler doesn't work.
I will have to render the JS on the client, in order for it to work :)

Categories