Showing an element with an if statement in nextJS - javascript

I'm trying to add a parameter to a nextJS components which only show if a condition is true.
Currently, I'm returning this:
return (
<div role="main" aria-label={this.props.title} className={Styles.main + " " + color}>
<h1>{this.props.title}</h1>
<h2>{this.props.sub}</h2>
<div className={Styles.buttons}>
<a className={Styles.button} href="#features">Features</a>
<a className={Styles.button} href="#commands">Commands</a>
<a className={Styles.button} href={this.props.inviteURL}>Invite</a>
{() => {
if (1==1) {
return (
<a className={Styles.button} href={this.props.sourceURL}>Source</a>
)
}
}}
</div>
</div>
);
Currently, it shows the top bit of the return and the buttons inside of that, but the one with the text Source isn't shown.
Why isn't it showing, and how do I fix it?

You are using a function that is never executed, so the component will never appear, it also expects an expression, so if you use simple if statements it won't work, as the following:
return (
<div role="main" aria-label={this.props.title} className={Styles.main + " " + color}>
<h1>{this.props.title}</h1>
<h2>{this.props.sub}</h2>
<div className={Styles.buttons}>
<a className={Styles.button} href="#features">Features</a>
<a className={Styles.button} href="#commands">Commands</a>
<a className={Styles.button} href={this.props.inviteURL}>Invite</a>
{if(1==1) {
return (
<a className={Styles.button} href={this.props.sourceURL}>Source</a>
)
}
}
</div>
</div>
);
I would suggest using ternary operators or && instead of an if which leaves you the following solution:
return (
<div role="main" aria-label={this.props.title} className={Styles.main + " " + color}>
<h1>{this.props.title}</h1>
<h2>{this.props.sub}</h2>
<div className={Styles.buttons}>
<a className={Styles.button} href="#features">Features</a>
<a className={Styles.button} href="#commands">Commands</a>
<a className={Styles.button} href={this.props.inviteURL}>Invite</a>
{1==1 && <a className={Styles.button} href={this.props.sourceURL}>Source</a>}
</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>

Combine two React files into one

I have two files that return html fragments. They are identical except for the image. The fact is that the server has different paths to the playlist image and the genre image.
props.items.images[0].url
and
props.items.icons[0].url
because of this, I had to distribute this code to two different files. How could I combine them into one?
const Playlist = props => {
const playListClick = e => {
props.onClick(e.target.title);
}
return (
<section id={props.selectedValue} className="column column__hidden" onClick={playListClick}>
<a className="link__decoration link__track hover__track link__one" href="#">
<div>
{props.items.map((item, idx) =>
<div className="container" key={idx + 1} title={item.id} >
<div className="content__track" title={item.id}>
<img className="img__tarck" title={item.id} src={item.images[0].url}/>
<div className="name" title={item.id}>{item.name}</div>
</div>
</div>)}
</div>
</a>
</section>
);
}
const Genre = props => {
const genreClick = e => {
props.onClick(e.target.title);
}
return (
<section id={props.selectedValue} className="column column__hidden" onClick={genreClick}>
<a className="link__decoration link__track hover__track link__one" href="#">
<div>
{props.items.map((item, idx) =>
<div className="container" key={idx + 1} title={item.id}>
<div className="content__track" title={item.id}>
<img className="img__tarck" title={item.id} src={item.icons[0].url}/>
<div className="name" title={item.id}>{item.name}</div>
</div>
</div>)}
</div>
</a>
</section>
);
You can use a Conditional (ternary) Operator to look if icons exists and if not fallback to using the image. Further assistance is hard due to not knowing the surrounding circumstances.
<img className="img__tarck" title={item.id} src={item.icons ? item.icons[0].url : item.images[0].url}/>

Convert string to real HTML in React.js

I received information from an API which comes with HTML. What happens is, when I try to display the information in the code, it transforms the HTML in a string and doesn't read as real HTML.
I search a lot and all I saw was the method of dangerouslySetInnerHTML but I also saw some reviews and comments about it and I don't want to use it if exists another solution. Also, I tried to use Fragmant but not success.
Below is my render() code:
return (
<div>
{models.map(model => (
<a href="/sofa">
<div className="Parcelas" key={model.id}>
<img
src={"url" + model.image}
className="ParcImage"
alt="sofa"
/>
<h1>Sofá {model.name}</h1>
<h2>
1,200<span>€</span>
</h2>
<p className="Features">{model.description}</p>
<button className="Botao">
<p className="MostraDepois">Ver Detalhes</p>
<span>+</span>
</button>
<img src="../../img/points.svg" className="Decoration" alt="points" />
</div>
</a>
))}
</div>
);
Here's an image showing:
If you have html in a string, you can use dangerouslySetInnerHTML to render it as html.
return (
<div>
{models.map(model => (
<a href="/sofa">
<div className="Parcelas" key={model.id}>
<img
src={"url" + model.image}
className="ParcImage"
alt="sofa"
/>
<h1>Sofá {model.name}</h1>
<h2>
1,200<span>€</span>
</h2>
<p
className="Features"
dangerouslySetInnerHTML={{ __html: model.description }}
/>
<button className="Botao">
<p className="MostraDepois">Ver Detalhes</p>
<span>+</span>
</button>
<img src="../../img/points.svg" className="Decoration" alt="points" />
</div>
</a>
))}
</div>
);
Check if the text you're trying to append to the node is no escaped like this:
model: {
description: '<h1>Hi there!</h1>'
}
Instead of this:
model: {
description: '<h1>Hi there!</h1>'
}
if is escaped you should convert it from your server-side.
if you can't try something like this:
<p className="Features">{model.description.fromCharCode(183)}</p>
Another option is a combination of ReactHtmlParser and unescapingHtml:
import ReactHtmlParser from "react-html-parser";
let model = [
{
description: "<h1>Hello There</h1>"
},
{
description: "<h1>Hello There</h1>"
}
];
function App() {
function unescapeHTML(html) {
var escapeEl = document.createElement("textarea");
escapeEl.innerHTML = html;
return escapeEl.textContent;
}
return (
<div className="App">
{model.map(des => {
return ReactHtmlParser(unescapeHTML(des.description));
})}
</div>
);
}

React todo list - how to make the filter work

handleFilters(filter){
console.log(filter);
}
render(){
return(
<div>
<a href="#" filter="show_all" onClick={this.handleFilters}>All</a>
{' '}
Active
{' '}
Completed
</div>
I am making a todo app and have it's working too, but I am having a bit of a problem adding the filters where I can show All todos, active todos, or the completed todos.
what I am trying to do at the moment is to get the value of filter from the a href tags and then will use it to filter the todo items from the list.
but at the moment, I am just trying to get the value of filter, so how do I do that?
You could avoid storing data in DOM like this
const match = filter => () => this.handleFilters(filter)
<div>
<a href="#" onClick={match('show_all')}>All</a>
{' '}
<a href="#" onClick={match('show_active')}>Active</a>
{' '}
<a href="#" onClick={match('show_completed')}>Completed</a>
</div>
handleFiltersShowActive(){
const tds = this.props.todos.foreach(todo =>
if(!todo.isCompleted)
Displaytodolist.push(todo);
);
this.setState(displaytodo: tds);
}
render(){
{todos} = this.props;
Let display = this.state.displaytodo.foreach( todo =>
visiblelist.push (
<div> {todo.title} </div>
);
);
return(
<div> <a href="#" filter="show_all" onClick={this.handleFilters}>All</a> {' '}
<a href="#" filter="show_active" onClick={this.handleFiltersShowActive}>Active</a> {' '}
Completed </div>
{display}
)};
Try this out.

reactjs, loop through an item and if condition on markup

I am working on a reactjs component. I have 3 items, that I am looping through - but I only wish to show a button, under the first item. I am getting a syntax error.
<div className='row grid__row--offset--50'>
<div className='small-55 medium-58 large-58 small-centered columns background--white--small border__transparent--top'>
{
lang.howTiles[0].items.map(function (item, index) {
return (
<div key={index}>
{index}
<div className='small-60 columns grid__row--offset--30 show-for-small-only'> </div>
<div className='small-45 medium-20 small-centered medium-uncentered columns'>
<div className='row'>
<div className='small-60 medium-45 small-centered columns'>
<div className='relative-container'>
<img className='centered' src={HowImage1} style={{maxWidth: '50%', marginLeft: '25%'}} />
<h3 className='text--bold text--center'><font><font>Project</font></font></h3>
<p className='text--center text--font-size-14'><font><font>Write out your project and show it to a hand-picked group of experts</font></font></p>
</div>
</div>
</div>
{
if(index==0){
<div className='grid__row--offset--40 row'>
<div className='small-40 columns small-centered'>
<a className='text--white text--center text--font-size-14 button medium radius secondary' href={lang.howTiles[0].button.url}><font><font>{lang.howTiles[0].button.title}</font></font></a>
<a href='http://localhost/slack'><img alt='Add to Slack' height='40' width='139' src='https://platform.slack-edge.com/img/add_to_slack.png' srcSet='https://platform.slack-edge.com/img/add_to_slack.png 1x, https://platform.slack-edge.com/img/add_to_slack#2x.png 2x' /></a>
</div>
</div>
}
}
</div>
</div>
)
})
}
<div className='medium-60 columns grid__row--offset--30'> </div>
</div>
<div className='row grid__row--offset--80'> </div>
</div>
We can't directly use if-else/switch statement inside JSX, use either ternary operator or call a function from JSX and use if-else/switch inside that.
Use this:
{
index == 0 ?
<div className='grid__row--offset--40 row'>
<div className='small-40 columns small-centered'>
<a className='text--white text--center text--font-size-14 button medium radius secondary' href={lang.howTiles[0].button.url}><font><font>{lang.howTiles[0].button.title}</font></font></a>
<a href='http://localhost/slack'><img alt='Add to Slack' height='40' width='139' src='https://platform.slack-edge.com/img/add_to_slack.png' srcSet='https://platform.slack-edge.com/img/add_to_slack.png 1x, https://platform.slack-edge.com/img/add_to_slack#2x.png 2x' /></a>
</div>
</div>
: null
}
Update:
Another possible solution is call a function from render method and use the if condition inside that, like this:
{
this._checkCondition()
}
_checkCondition(index){
if(index == 0){
return (
<div className='grid__row--offset--40 row'>
<div className='small-40 columns small-centered'>
<a className='text--white text--center text--font-size-14 button medium radius secondary' href={lang.howTiles[0].button.url}><font><font>{lang.howTiles[0].button.title}</font></font></a>
<a href='http://localhost/slack'><img alt='Add to Slack' height='40' width='139' src='https://platform.slack-edge.com/img/add_to_slack.png' srcSet='https://platform.slack-edge.com/img/add_to_slack.png 1x, https://platform.slack-edge.com/img/add_to_slack#2x.png 2x' /></a>
</div>
</div>
)
}
}
For more details why we can't use if-else in JSX check the DOC.
Or you can try other approach. If index==false all between () will be rendered. Remember - javascript has dynamic typing
{!index &&
(<div className='grid__row--offset--40 row'>
<div className='small-40 columns small-centered'>
<a className='text--white text--center text--font-size-14 button medium radius secondary' href={lang.howTiles[0].button.url}><font><font>{lang.howTiles[0].button.title}</font></font></a>
<a href='http://localhost/slack'><img alt='Add to Slack' height='40' width='139' src='https://platform.slack-edge.com/img/add_to_slack.png' srcSet='https://platform.slack-edge.com/img/add_to_slack.png 1x, https://platform.slack-edge.com/img/add_to_slack#2x.png 2x' /></a>
</div>
</div>)}

Categories