I am trying to implement nested if else in react compound slider.
I am able to write if else using ternary operator and that is working fine
<div className={source.value >.3 ? 'greater': 'lesser'}>
<Track
key={id}
source={source}
target={target}
getTrackProps={getTrackProps}
/>
</div>
so here i am able to check only condition whether it is greater than .3 or less than but am trying to implement
if(source.value <.3)
{
return classNameFirst
}
else if (source.value >.3 && source.value <.7){
return classnameSecond
}
else if (source.value >.7 && source.value <.9){
return classnamethird
}
else if (source.value >.9 && source.value <1.2){
return classnameFourth
}
else{
return classnamefive
}
how can i implement this thing into my jsx code.
Thanks in advance.
Define a function in your helper or utility file. You can also define the function in your class itself, but generally it is a good idea to use helper file for this.
So you can have a function getTrackClass which will accept source.value as the parameter and return you the appropriate class.
getTrackClass = value => {
if (value < 0.3) {
return classNameFirst;
} else if (value > 0.3 && value < 0.7) {
return classnameSecond;
} else if (value > 0.7 && value < 0.9) {
return classnamethird;
} else if (value > 0.9 && value < 1.2) {
return classnameFourth;
} else {
return classnamefive;
}
};
After this you can use this function to get the class for your Track component.
<div className={this.getTrackClass(source.value)}>
<Track
key={id}
source={source}
target={target}
getTrackProps={getTrackProps}
/>
</div>
Use the package named classNames in your application.
https://www.npmjs.com/package/classnames
This will give you the flexibility of using multiple classes, but will also allow you to use classes conditionally in a more readable way.
Is this what you're trying to accomplish?
return(
source.value < .3 ?
classNameFirst
: source.value < .7 ?
classNameSecond
: source.value < .9 ?
classNameThird
: source.value < 1.2 ?
classNameFourth
: classNameFive
);
Related
I have two different containers that call ControlSection component. One pass bestScore prop and the second pass level prop.
In the ControlSection component I want to display the prop in <h2> only if they pass from the container. How can I do it?
const ControlSection = ({ score, bestScore, level }) => {
return (
<div className='controlSection'>
<div className='gameStatistics'>
<h2>Score: {score}</h2>
{bestScore ? <h2>Best: {bestScore}</h2>}
{level ? <h2>Level: {level}</h2>}
</div>
</div>
)
}
The term you're looking for is Conditional Rendering and the standard way to render a component when the prop is defined is by using the && operator.
{bestScore && <h2>Best: {bestScore}</h2>}
The second part, <h2>Best: {bestScore}</h2>, will only be rendered if bestScore is true. (you could use any other condition here)
This is because in JS, undefined, null, 0, '' and NaN are evaluated as false (falsy).
false && <h1>something</h1> will be evaluated as false, therefore it won't be rendered.
Coming back to the bestScore prop, it could also be 0 and evaluated as falsy. You need to take care of that. Something like this could work:
{(bestScore || bestScore === 0) && <h2>Best: {bestScore}</h2>}
What I would do in your case is the following to cover your requirement:
const ControlSection = ({ score, bestScore, level }) => {
return (
<div className='controlSection'>
<div className='gameStatistics'>
<h2>Score: {score}</h2>
{bestScore != null ? <h2>Best: {bestScore}</h2> : null}
{level != null ? <h2>Level: {level}</h2> : null}
</div>
</div>
)
}
By doing bestScore != null the code identifies 2 different things as false which are null and undefined. Please refer to the following code example:
let bestScore = null;
console.log('testing for null value:', bestScore != null);
bestScore = undefined;
console.log('testing for undefined value:', bestScore != null);
bestScore = '';
console.log('testing for \'\' value:', bestScore != null);
bestScore = 0;
console.log('testing for 0 value:', bestScore != null);
In false value case the h2 tag won't be rendered in your component thus you have covered 2 cases where you have either undefined or null value from properties.
To handle 0 and '' values you might want to do the following:
function hasToRender(value) {
if (value === '') {
return false;
} else if (value == 0) {
return true;
} else if (value != null) {
return true;
}
return false;
}
console.log('null', hasToRender(null));
console.log('undefined', hasToRender(undefined));
console.log('\'\'', hasToRender(''));
console.log(0, hasToRender(0));
console.log(17, hasToRender(17));
So I think the working solution would be the following in your case to cover all the cases:
const ControlSection = ({ score, bestScore, level }) => {
function hasToRender(value) {
if (value === '') {
return false;
} else if (value == 0) {
return true;
} else if (value != null) {
return true;
}
return false;
}
return (
<div className='controlSection'>
<div className='gameStatistics'>
<h2>Score: {score}</h2>
{hasToRender(bestScore) ? <h2>Best: {bestScore}</h2> : null}
{hasToRender(level) ? <h2>Level: {level}</h2> : null}
</div>
</div>
)
}
Of course the hasToRender function can be simplified further but this gives you the idea, hope this helps!
{typeof bestScore !== 'undefined' && <h2>Best: {bestScore}</h2>}
or
{typeof level === 'number' && <h2>Level: {level}</h2>}
for (var k = 0; k < 10; k++) {
if (k % 2 === 0) {
weatherText = <div className="in_break">
}
weatherText += <div className="eachD" key={k}>
<div>
{
countIt === 0 ? (currDate.getHours() > 12 ? "Tonight" : "Today") : dayOfWeek[weekDay]
}
</div>
<div>
{
getDate
}
</div>
<div>
{
<ReturnIcon />
}
</div>
</div>
if (k % 2 === 0) {
weatherText += </div>
}
}
What I am looking to do is group all the eachD by two inside the `in_break' div
But I keep getting:
Parsing error: Unexpected token 'weatherText = </div>'
This is the layout:
in_break
eachD
eachD
in_break
eachD
eachD
in_break
eachD
eachD
...
Please help me resolve my issue
UPDATED
I hope this find it's way to your demand:
setWeatherTextItems = (countId, currDate, dayOfWeek, weekDay, getDate) => {
// you make sure all the variables such like countId and currDate are available inside this function.
const items = [];
for (var k = 0; k < 10; k++) {
items.push(
<div className="eachD" key={k}>
<div>
{countIt === 0
? currDate.getHours() > 12
? "Tonight"
: "Today"
: dayOfWeek[weekDay]}
</div>
<div>{getDate}</div>
<div>{<ReturnIcon />}</div>
</div>
);
}
return items;
}
renderInBreak = () => {
const items = this.setWeatherTextItems();
const inBreakItems = [];
let breakBlock = [];
let newBreak = false;
items.forEach((textItem, index) => { //1
if(!newBreak) {
breakBlock.push(textItem);
if(index + 1 === items.length){
inBreakItems.push(breakBlock);
}
} else {
inBreakItems.push(breakBlock);
breakBlock = [];
breakBlock.push(textItem);
//without this condition check, the last element will be left out of an odd array length
if(index + 1 === items.length) {
inBreakItems.push(breakBlock)
}
}
if(index % 2) newBreak = true; //false
else newBreak = false; //false
});
return inBreakItems.map(twoTextWeatherItems => (
<div className="in_break">
{twoTextWeatherItems}
</div>
))
}
render(){
<div>
{this.renderInBreak()}
</div>
}
OLD
React is supposed to handle things differently, maybe this will work:
Define a method in your component that will set your items:
setWeatherTextItems = (countId, currDate, dayOfWeek, weekDay, getDate) => {
// you make sure all the variables such like countId and currDate are available inside this function.
const items = [];
for (var k = 0; k < 10; k++) {
items.push(
<div className="eachD" key={k}>
<div>
{countIt === 0
? currDate.getHours() > 12
? "Tonight"
: "Today"
: dayOfWeek[weekDay]}
</div>
<div>{getDate}</div>
<div>{<ReturnIcon />}</div>
</div>
);
}
return items;
}
in your render method, or where you are willing to render these items:
render(){
<div className="in_break">{this.setWeatherTextItems()}</div>
}
Read more about how to render things in a loop.
You can add the conditions you want inside the for loop, or where it makes sense to you.
Not sure if the logic would work in a react environment but as far as I can see from your plain code when you are going to add the 'in_break' div aren't you just assigning the whole whetherText again instead of joining text to it?
Shouldn't this:
if (k % 2 === 0) {
weatherText = </div>
}
be written like this?
if (k % 2 === 0) {
weatherText += </div>
}
Edit following the typo correction:
I tried to run your code on codepen to have a quicker and easier understanding on how to find a solution.
I created an helper function with your code then I returned
<div className="Container" dangerouslySetInnerHTML={{__html: weatherText}}></div>
This enables you to have the result you are looking for. Only the even elements have the 'in_break' class.
Hope this helped and let me know if this is not correct.
Codepen: https://codepen.io/dpgian/pen/EBzRmX
Hello there I need help in converting this 'if-else' with 'or' condition into conditon that can be used in ng-class.
This here is my ng-class with condition, but it's not working correctly.
<span ng-class="{'green': work > toWork,
'red': work < toWork,
'black': work == toWork || overall == '-'}">
{{overall = showMonthly(work = (workers | getMonthValue: dts.value),
toWork = getMonthlyToWork(member.id, dts.value))}}
</span>
this is the condition I'd like to apply:
if (work > toWork) {
return "green";
}else if (work < toWork) {
return "red";
}else if (work == toWork || overall == "-") {
return "black";
}
You don't need ng-class for that, you just need to put the logic inside a method in your $scope, like below
$scope.getClass = function(work, toWork, overall){
if (work == toWork || overall == "-"){
return "black";
}else if (work < toWork) {
return "red";
}else if(work > toWork) {
return "green";
}
}
and in your view, call it like this
<span class="{{getClass(work, toWork, overall)}}"></span>
<span ng-class="{'green': work > toWork,
'red': work < toWork,
'black': (work == toWork || overall == '-')}">
...
</span>
Check this. (You have got a spell missing in your conditional statement)
Happy coding!
I'm trying to wrap every two posts inside a container div. Below is what I tried, but unfortunately I get an error.
This is what I tried:
I have a variable called postIndex. While the posts are being iterated over with posts.map(({ node }) => {...}, I have a conditional if/else check to see if postIndex is odd or even with if (postIndex % 2 == 0) (check if postIndex is even) and if (postIndex % 2 == 1) (check if postIndex is odd).
If postIndex is even I render out only the opening <div> tag that is the container for the two posts. If postIndex is odd, then I render out only the closing </div> tag.
I get an error with this implementation, though. What is the right way to go about doing something like this?
Example of what I tried:
let postIndex = 0
return (
<Layout>
{posts.map(({ node }) => {
if (postIndex % 2 == 0) {
postIndex++
return (
<div>
<p>test</p>
)
} else if(postIndex % 2 == 1) {
postIndex++
return (
<p>Test</p>
</div>
)
}
})
}
</Layout>
)
An opening tag without a closing tag is invalid JSX. You can probably do something like this below though. Also, you have access to the index of the array in a map, so you don't need to create a new variable.
return (
<Layout>
{posts.map(({ node }, index) => {
if (index % 2 === 0) {
return (
<div key={index}>
<p>{node}</p>
{posts[index + 1] && <p>{posts[index + 1].node}</p>}
</div>
)
}
})
}
</Layout>
)
I'm looking how to make a repeat item carousel which has if just key 0 that have class action if I using it in return it's error and if I using variable in return pug .carousel-item${activeornot}
return _.map(this.props.editor_pick_data, function (value, key){
if(key == 0){
}
return (
pug`
.carousel-item.active(key=${key}, style=${{display: 'relative'}})
.col-md-3.col-sm-6.col-xs-12npm
a.thumbnail(href="#")
img.img-responsive(src=${value.item.images[1].big_thumbnail})
`
)
})
It looks like you're just trying to add active class if key === 0. I think you can have a className variable as well:
className=${key == 0 ? 'active' : ''}
-
renderCarouselItem() {
return _.map(this.props.editor_pick_data, function(value, key) {
return (
pug`
.carousel-item(key=${key}, style=${{display: 'relative'}}, className=${key == 0 ? 'active' : ''})
.col-md-3.col-sm-6.col-xs-12npm
a.thumbnail(href="#")
img.img-responsive(src=${value.item.images[1].big_thumbnail})
`
);
})
}
Maybe you can do something like this:
className={`carousel-item ${key == 0 ? 'active' : ''}`}
this work but i dont know this is the best practice
renderCarouselItem() {
return _.map(this.props.editor_pick_data, function (value, key){
let html = [];
if(key == 0){
html.push(pug`
.carousel-item.active(key=${key}, style=${{display: 'relative'}})
.col-md-3.col-sm-6.col-xs-12npm
a.thumbnail(href="#")
img.img-responsive(src=${value.item.images[1].big_thumbnail})
`)
}else{
html.push(pug`
.carousel-item(key=${key}, style=${{display: 'relative'}})
.col-md-3.col-sm-6.col-xs-12npm
a.thumbnail(href="#")
img.img-responsive(src=${value.item.images[1].big_thumbnail})
`)
}
return (
pug`
${html[0]}
`
)
})
}