In my react app I'm using IF statement inside another IF statement to validate a condition that I want to get data filtered only from a specific column not from all.
Basically I'm using AntD table in which I'm displaying students data. In a table I do have few columns namely Age, Marks and Attendance. On each column(Age, Marks and Attendance) I'm applying a range filter with aim to fetch student(s) when applied search on a specific column i.e. either Age, Marks or on Attendance.
The problem I'm getting that my Nested-IF condition is not validating to true. Rest of code is working fine. I also tried to run code without Nested-IF(I mean with the simple IF/ELSE statement). That is also working fine.
I don't know what did I wrong or what I'm missing/skipping in my attempt.
Help me to validate my Nested-IF/ELSE statement(s).
What I'm trying is:
const handleSearch = (firstInput, secondInput, dataIndex) => {
setSearchStu(
student.filter((obj) => {
if (dataIndex === "age") {
if (obj.age >= firstInput && obj.age <= secondInput) {
return true;
} else {
return false;
}
} else {
if (dataIndex === "marks") {
if (obj.marks >= firstInput && obj.marks <= secondInput) {
return true;
} else {
return false;
}
} else {
if (dataIndex === "attendance") {
if (obj.attendance >= firstInput && obj.attendance <= secondInput) {
return true;
} else {
return false;
}
} else {
return false;
}
}
}
})
);
};
Where
firstInput is the 1st input field in a range filter
secondInput is the 2nd input field in a range filter
dataIndex is like a key to validate my 1st IF statement in Nested-IF case
Values "age", "marks" and "attendance" are the defined values which are uniquely correspond to the each columns(Age, Marks and Attendance) in the table
and so on..
Thank you in advance for your assistance.
to simplfy your code, you can try this :
const handleSearch = (firstInput, secondInput, dataIndex) => {
setSearchStu(
student.filter((obj) => {
if (dataIndex === "age") {
return (obj.age >= firstInput && obj.age <= secondInput)
} else {
if (dataIndex === "marks") {
return (obj.marks >= firstInput && obj.marks <= secondInput)
} else {
if (dataIndex === "attendance") {
return (obj.attendance >= firstInput && obj.attendance <= secondInput)
} else {
return false;
}
}
}
})
);
};
or like this :
switch(dataIndex){
case "age" :
return (obj.age >= firstInput && obj.age <= secondInput)
break;
case "marks" :
return (obj.marks >= firstInput && obj.marks <= secondInput)
break;
case "attendance" :
return (obj.attendance >= firstInput && obj.attendance <= secondInput)
break;
default :
return false
}
The function does work given the right inputs and data - I made a sandbox on replit to verify. Possibly there is an issue with the student data (consider renaming to students) or with the inputs to the function. Also, the function can be simplified to the following (see replit sandbox):
const handleSearch = (firstInput, secondInput, dataIndex) => {
return (
student.filter((obj) => {
if (["age", "marks", "attendance"].includes(dataIndex)) {
return obj[dataIndex] >= firstInput && obj[dataIndex] <= secondInput
}
return false
})
);
};
Related
I'm working on a project, and I need the English version of countries' names. I'm trying to have an if/else statement that will give the English spelling when the non-English spelling of a country is given, but it's not working. I would really appreciate any help or advice on why I am having this issue. Thank you!
let countryName;
if (country === 'Shqipëria' || 'hqipëria') {
let countryName ='Albania';
}
else if (country === 'Hayastán' || 'hayastán') {
let countryName ='Armenia';
}
...
else if (country === 'Italia' || 'italia') {
let countryName ='Italy';
}
...
else if (country === 'Türkiye' || 'türkiye') {
let countryName = 'Turkey';
}
else if (country === 'Ukraїna' || 'Україна' || 'ukraїna' || 'yкраїна') {
let countryName = 'Ukraine';
}
else {
let countryName = country;
}
console.log(countryName)
console.log(country)
console.log(country) gives Italia, but console.log(countryName) is undefined.
I have also tried doing this:
const [countryName, setCountryName] = useState('')
if (country === 'Shqipëria' || 'hqipëria') {
setCountryName('Albania');
}
else if (country === 'Hayastán' || 'hayastán') {
setCountryName('Armenia');
}
...
else if (country === 'Italia' || 'italia') {
setCountryName('Italy');
}
...
else if (country === 'Türkiye' || 'türkiye') {
setCountryName('Turkey');
}
else if (country === 'Ukraїna' || 'Україна' || 'ukraїna' || 'yкраїна') {
setCountryName('Ukraine');
}
else {
setCountryName(country);
}
console.log(countryName)
console.log(country)
But this was giving me an error stating Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
as mentioned in other answers your conditions only contain one equality check, so it wold always return true because a string's value by-itself is truthy, so you never get passed the first condition. for simplifying if statements, you can use the includes method. for example:
if (['Ukraїna','Україна','ukraїna','yкраїна'].includes(country))
and definitely declare country variable once & re-assign it in every condition.
let countryName;
if (...) {
countryName = "x"
}
Cancerning your first code: countryname shouldn't be declared many times
so your code should be like this:
let countryName;
if (country === 'Shqipëria' || country === 'hqipëria') {
countryName ='Albania';
}
else if (country === 'Hayastán' || country === 'hayastán') {
countryName ='Armenia';
}
else if (country === 'Italia' || country === 'italia') {
countryName ='Italy';
}
else if (country === 'Türkiye' || country === 'türkiye') {
countryName = 'Turkey';
}
else if (country === 'Ukraїna' || country === 'Україна' || country === 'ukraїna' || country === 'yкраїна') {
countryName = 'Ukraine';
}
else {
countryName = country;
}
console.log(countryName);
console.log(country);
Also, you should use
if(variable === 'value' || variable === 'value')
instead of
if (variable === 'value' || 'value')
I want to submit some data but if the textarea (name) is empty or null i want to use the value of the select to search, but for some reason my if/else doesn't work and always search using the name even if its empty and this gives an error beaacause it's empty
e.preventDefault();
if (name != null || name !== '') {
try {
setNameIntroduced(true);
let cardFound = completeArrayCards.filter((e) => e.name.toLowerCase() === name.toLowerCase());
setCardFoundIndividual(cardFound);
let arrayImages = Object.keys(cardFound[0].image)
.map(function (key) {
return cardFound[0].image[key];
});
if (cardFound[0].name !== null) {
setFound(true);
setName(cardFound[0].name);
setType(cardFound[0].type);
setImage(arrayImages[1]);
setAttribute(cardFound[0].attribute || cardFound[0].type);
setDescription(cardFound[0].desc);
setLevel(cardFound[0].level);
setRace(cardFound[0].race);
setAtk(cardFound[0].atk);
setDef(cardFound[0].def);
setCardsets(cardFound[0].card_sets);
setCardPrices(Object.keys(cardFound[0].card_prices)
.map(function (key) {
return cardFound[0].card_prices[key];
}));
if (type === 'Spell Card' || type === 'Trap Card') setIsMagicTrap(true)
}
} catch (err) {
console.log(err);
setFound(false);
}
} else if (name == null && type != null) {
try {
setMultipleResults(true);
setFound(true);
setNameIntroduced(false);
let cardsFound = completeArrayCards.filter((e) => e.type === type);
//console.log(cardsFound);
console.log('Multiple found: ' + cardsFound[0].name + '\n' + cardsFound[0].type + '\n' + cardsFound[0].image.image_url);
} catch (err) {
console.log(err);
setFound(false);
}
}
}```
I am new to React, so I am probably not using best practices. I am trying to build this "Simon Says" game, but I am stuck trying to put delay in between each of my for loops, they run at the same time. I've looked at other solutions for this but they don't seem to fit with mine. I've also tried using setTimeout but that just plays all the animations at once after the delay. This is the for loop and the functions i want to have a delay in between:
newRound() {
this.setState({
pcSequence: this.state.pcSequence.concat(
Math.floor(Math.random() * 4) + 1)
},() => {
this.state.pcSequence.forEach(element =>
this.startAnimations(element)
);
}
);
}
startAnimations(element) {
if (element == 1) {
this.activeBtn1(0);
} else if (element == 2) {
this.activeBtn2(1);
} else if (element == 3) {
this.activeBtn3(2);
} else if (element == 4) {
this.activeBtn4(3);
}
}
Thanks!!
Hi I like your question and manage to get it working, i will share code below:
state = {
pcSequence: [],
}
componentDidMount() {
this.newRound();
}
newRound() {
this.setState({
pcSequence: [1,4,3,2]
},() => this.startSequence()
);
}
startSequence() {
if (this.state.pcSequence.length > 0) {
setTimeout(() => {
this.startAnimations(this.state.pcSequence.pop());
this.startSequence();
}, 1000) // 1000ms === 1 second
}
}
startAnimations(element) {
if (element === 1) {
console.log('element 1', element)
} else if (element === 2) {
console.log('element 2', element)
} else if (element === 3) {
console.log('element 3', element)
} else if (element === 4) {
console.log('element 4', element)
}
}
you can call this.newRound each time you want to reset buttons and also fill the array in a better way, yours is only filling the array with 1 item not 4 like [1] or [4]
Hope it helps!
I found help elsewhere and wanted to show what I did in case anyone else ever comes along looking for something similar. I removed the for loop and used map:
newRound() {
this.setState({
pcSequence: this.state.pcSequence.concat(
Math.floor(Math.random() * 4) + 1),
round: this.state.round + 1
},() => {
this.state.pcSequence.map((element,index)=> {
setTimeout(() => {
this.startAnimations(element);
}, index * 1000);
})
}
);
}
startAnimations(element) {
if (element == 1) {
this.activeBtn1(0);
} else if (element == 2) {
this.activeBtn2(1);
} else if (element == 3) {
this.activeBtn3(2);
} else if (element == 4) {
this.activeBtn4(3);
}
}
handleClick=()=>{
console.log("final course values"+ " "+this.state.selectCourseValue)
console.log("selected teacher"+ " "+this.state.selectedTeacher)
if(this.state.selectCourseValue ===null && this.state.selectedTeacher !== undefined)
{
console.log("please select")
message.warning('Add course')
return;
}
else{
console.log("Sucessfully updated")
}
}
If selectCourseValue is an array, then your condition should be probably this:
if (this.state.selectedTeacher && (this.state.selectCourseValue || []).length === 0) {
}
Checking that selectedTeacher is not empty and selectCourseValue is empty.
im using ag-Grid, but there is a issue when it filters my data, when i filter my data in the price column, it only works with numbers dot and not with commas.
Link: https://plnkr.co/edit/LDdrRbANSalvb4Iwh5mp?p=preview
Practical Example:
In the Price column select box equal and above insert "1.5" and than try inserting "1,5"
This is because this filter is a native one.
If you want to handle custom behaviour, define your own filter.
Documentation : https://www.ag-grid.com/angular-grid-filtering/index.php
A quick and dirty solution would be to monkey patch the NumberFilter like this :
NumberFilter.prototype.doesFilterPass = function (node) {
if (this.filterNumber === null) {
return true;
}
var value = this.valueGetter(node);
if (!value && value !== 0) {
return false;
}
var valueAsNumber;
if (typeof value === 'number') {
valueAsNumber = value;
}
else {
valueAsNumber = parseFloat(value.replace(',','.'));
}
switch (this.filterType) {
case EQUALS:
return valueAsNumber === this.filterNumber;
case LESS_THAN:
return valueAsNumber < this.filterNumber;
case GREATER_THAN:
return valueAsNumber > this.filterNumber;
default:
// should never happen
console.warn('invalid filter type ' + this.filterType);
return false;
}
};
Then changed line is here :
valueAsNumber = parseFloat(value.replace(',','.'));
So i found the problem, first i had to convert the value has a string than i needed to replace the dot by the comma, the problem with the answer above was first because of the data type and than the order of the properties of the replace function, but the problem now is that is not filtering correctly, if i search using equal option if gives me 2 values, instead a fixed one, code looks something like this:
Code:
NumberFilter.prototype.doesFilterPass = function (node) {
if (this.filterNumber === null) {
return true;
}
var value = this.valueGetter(node);
if (!value && value !== 0) {
return false;
}
var valueAsNumber;
if (typeof value === 'number') {
value = value.toString()
valueAsNumber = parseFloat(value.replace('.',','));
}
else {
valueAsNumber = parseFloat(value.replace('.',','));
}
switch (this.filterType) {
case EQUALS:
return valueAsNumber === this.filterNumber;
case LESS_THAN:
return valueAsNumber < this.filterNumber;
case GREATER_THAN:
return valueAsNumber > this.filterNumber;
default:
// should never happen
console.warn('invalid filter type ' + this.filterType);
return false;
}
};
Possible Solution:
NumberFilter.prototype.onFilterChanged = function () {
var filterText = utils_1.default.makeNull(this.eFilterTextField.value);
if (filterText && filterText.trim() === '') {
filterText = null;
}
var newFilter;
if (filterText !== null && filterText !== undefined) {
console.log(filterText);
// replace comma by dot
newFilter = parseFloat(filterText.replace(/,/g, '.'));
console.log(newFilter);
}
else {
newFilter = null;
}
if (this.filterNumber !== newFilter) {
this.filterNumber = newFilter;
this.filterChanged();
}
};