I'm missing something if someone can please explain it to me. I'm trying to re-write existing code into the ternary operator way.
I'm getting the following console error :
Uncaught SyntaxError: Unexpected token }
which I understand there's a condition not properly formatted which I can't seem to find. So I'm not sure what I'm missing or if I maybe misunderstand something in the filter function? Isn't the ? item.verified === true not suppose to automatically return the objects that's true?
var engagement = "social";
var audience = [{ 'verified': true, 'name': 'Steve'},
{ 'verified': false, 'name': 'Phil'},
{ 'verified': true, 'name': 'Jason'}];
let data = [];
data = audience.filter((item) => {
(engagement === "social")
? item.verified === true
: (engagement === 'social-crm')
? item.verified === false
: (engagement === 'all')
? item
})
The syntax that I understand:
data = audience.filter((item) => {
if (this.engagement === 'social-crm') {
return item.verified === true;
} else if (this.engagement === 'social') {
return item.verified === false;
} else if (this.engagement === 'all') {
return item;
}
});
Here's the fiddle I've been trying to play around with:
https://jsfiddle.net/phfilly/ya73e325/7/
Yup. Your syntax isn't right. To understand why your code isn't working, it would help if you were to re-write your if-else statements a bit.
if (this.engagement === 'social-crm') {
return item.verified === true;
} else if (this.engagement === 'social') {
return item.verified === false;
} else if (this.engagement === 'all') {
return item;
}
To this:
if(this.engagement === 'social-crm') { return item.verified === true; }
else {
if(this.engagement === 'social') {item.verified === false; }
else {
if(this.engagement === 'all') {return item;}
}
}
Now, ternary operators follow a similar nested fashion.
cond1 ? val1 : ( val2 )
Where val2 => cond2 ? val3 : (val4)
Where val4 => cond3 ? val5 : val6
So, now you can rewrite your expression like this:
this.engagement === 'social-crm' ? item.verified === true :
(this.engagement === 'social' ? item.verified === false :
(this.engagement === 'all' ? item : null))
The parenthesis matters here, because it closely mimics the nested if-elses from above.
Also note that for the inner most expression, a return value in the else must be specified. I've set it to null but you can return what you want. Do note this is the actual reason your code was failing. Apologies if the answer was long but I wanted to help you understand nested ternary operators.
A ternary operator looks like this:
something = (condition) ? a_value : a_different_value;
You forgot : a_different_value on the last case.
A nested ternary operator looks like this:
something = condition ? nested_condition ? value_if_both_conditions_are_true
: value_if_nested_condition_is_false : value_if_condition_is_false;
This works even without parentheses, but as others have mentioned, it can be hard to read. Especially when multiple conditions are checked, by use of && or || in the condition parts of this example.
Try this
You have to have a Condition for the Ternary operator as pointed by #Quentin
data = audience.filter((item) => { (engagement === "social") ?
item.verified === true : (engagement === 'social-crm') ?
item.verified === false : (engagement === 'all')?
item : null})
Deep nesting can write in a simpler way like this for ternary if-else
let userName = 'Amoos'
let isStudent = false
let age = 7
userName
? console.log(`User name: ${userName} 😊`)
: console.log('Unknow user');
isStudent ? console.log("Yes, is student 👨🎓")
: console.log('No, not a student 👨🎓');
(age<18) ? console.log("Younger 👶")
: console.log("Elder 😁")
Related
I am creating an application with a requirement for 2 search bars. One to search by name and another to search by tag. The search should also work when the user puts both name and tag in the searchbars.
The data from the api is in the format
{
"students" : [
{
"city": "city",
"company" : "company",
"email" : "email",
"firstName" : "firstName",
"grades" : ["12", "54"],
"id" : "1",
"lastName" : "lastName",
"pic" : "url",
"skill" : "skill"
},
],
}
My application is running on https://temp-application.netlify.app/
Currently the application does search with name as it is supposed to be.
But as soon as I attach search by tag functionality with it. Everything breaks down.
This is how I implemented searching by both name and tag.
useEffect(() => {
let filteredResults = results.filter((result) => {
const name = result.firstName + " " + result.lastName;
const isName = name
.toLowerCase()
.includes(searchName.toLowerCase());
const tags =
result.tag !== undefined ? result.tag.toString() : false;
const isTag =
typeof tags === "string"
? tags.toLowerCase().includes(searchTag.toLowerCase())
: false;
return isName && isTag;
});
setStudents(filteredResults);
}, [searchName, searchTag]);
Notice that 'tag' array is not present in the object returned by the API
The link you gave is not working.
For Tags, you are searching in the "tag" string in the Student(result) object but there is no key named tag in the given data.
Even if you have the tag key, you are probably not getting the result because you are doing a "&&" instead of "||"
I solved it. The problem was that I was trying to do the search in one-go. But instead I needed to make a if-else chain to achieve the result.
Here is the final function
let filteredResults = results.filter((result) => {
const name = result.firstName + " " + result.lastName;
const tags =
result.tag !== undefined ? result.tag.toString() : false;
if (searchName !== "" && searchTag === "") {
return name.toLowerCase().includes(searchName.toLowerCase());
} else if (searchName === "" && searchTag !== "") {
return typeof tags === "string"
? tags.toLowerCase().includes(searchTag.toLowerCase())
: false;
} else if (searchName !== "" && searchTag !== "") {
const isName = name
.toLowerCase()
.includes(searchName.toLowerCase());
const isTag =
typeof tags === "string"
? tags.toLowerCase().includes(searchTag.toLowerCase())
: false;
return isName && isTag;
} else if (searchName === "" && searchTag === "") {
return true;
}
return false;
});
setStudents(filteredResults);
}, [searchName, searchTag]);
i want to use ternary operator instead of if else conditions in react.
What i am trying to do?
I have an array of object type named 'list_info' which has type, recipient_idand recipient_email attributes.
Now i have a method named "get_text" which returns text whose value is string "to you" or the recipient email.
If the list_info type is "type_1" and props.current_user_id === list_info.recipient_id then it should
return nothing.
If the list_info type is "type_1" and props.current_user_id !== list_info.recipient_id then it should
return the list_info.recipient_email.
Now when the list_info type is anything other than "type_1" and and props.current_user_id ===
list_info.recipient_id then it should
return string "to you".
If the list_info type is anything other than "type_1" and props.current_user_id !==
list_info.recipient_id then it should return the list_info.recipient_email.
So to accomplish the above conditions i have the "get_text" method as below,
get_text = () => {
const list_info = this.props.list_info;
let text;
if (this.props.list_info.type === 'type_1') {
if (this.props.current_user_id === list_info.recipient_id) {
text = '';
} else {
text = list_info.recipient_email;
}
} else {
text = this.props.current_user_id === list_info.recipient_id
? 'you'
: list_info.recipient_email;
}
return <strong key={list_info.type}>{text}</strong>;
};
The above code works. But i think it could be made even more simple to read using ternary operator. could someone help me fix this. thanks.
Generally writing nested ternary operators will make the code unreadable. You can refactor your code as below, if you have more and more conditions/logic coming in, you can probably start using switch statement.
get_text = () => {
const { list_info, current_user_id } = this.props;
const meTextByType = list_info.type === 'type_1' ? "" : "you";
let text = current_user_id === list_info.recipient_id ?
meTextByType :
list_info.recipient_email;
return <strong key={list_info.type}>{text}</strong>;
};
get_text = () => {
const { list_info, current_user_id } = this.props;
const { type, recipient_id, recipient_email } = list_info;
const meTextByType = type === 'type_1' ? "" : "you";
let text = current_user_id === recipient_id ? meTextByType :brecipient_email;
return <strong key={type}>{text}</strong>;
};
How about local functions that describe exactly what each condition is, and by the looks of you only ever return 2 values, either 'to you' or the recipient_email prop.
getText = () => {
const isToYou = () => listInfoType !== 'type_1' && recipientId === userId
return isToYou() ? 'To You' : recipientEmail
}
I am saving a record on button click but it always throwing an error.
I am including an if else condition. I have surpassed all the conditions but still my code is going to the if condition but It should not go to if condition.
code is -
my this.state.question.options value is -
[
{
id:3250,
label:'good answer',
assert:1
position:1
},
{
id:3249,
label:'bad answer',
assert:0
position:2
}
]
and I am checking if else condition as -
if (this.state.question.options.filter(o => o.assert === true).length <= 0) {
hasError = true
errorKey = 'add-question-modal-missing-assert-options'
}
else {
alert("test");
}
my code should goto else part and print test as alert but it is going to if part and showing error. Why ?
I wanna show else part i.e test as alert
You are using the strict comparison operator (===) while comparing 2 different values. In your example, 1 is being parsed as an integer, while true is being parsed as a boolean. A strict comparison operator is used to check 2 values on equal values AND equal types.
To fix the error in your code, use a loose comparison (==) or convert the integer to a boolean by using !!1
if (this.state.question.options.filter((el) => {return !!el.assert}).length <= 0) {
hasError = true
errorKey = 'add-question-modal-missing-assert-options'
}
else {
alert("test");
}
In JavaScript, 1 is not strictly equal to true. However, it is a good practice to use the strict equality operator ===.
You should compare o.assert with the real possible value o.assert === 1.
In terms of readability I would also consider comparing the length to 1 instead of 0:
this.state.question.options.filter(option => option.assert === 1).length < 1
this.state.question.options value is -
[
{
id:3250,
label:'good answer',
assert:1,
position:1
},
{
id:3249,
label:'bad answer',
assert:0,
position:2
}
]
and then
if (this.state.question.options.filter(o => o.assert == true)).length <= 0) {
hasError = true
errorKey = 'add-question-modal-missing-assert-options'
} else {
alert("test");
}
replace === strict type with ==
Do u want this kind of code
if (this.state.question.options.length <= 0) {
assert = true;
hasError = true;
errorKey = 'add-question-modal-missing-assert-options'
}
else {
alert("test");
}
I want to create a function that can be general as possible but It doesn't work now.
I have two case :
Check if the state of a state is not empty or true and if my item is equal to him, I want to reset him by calling resetState() and set to false and empty string
Check if the state of a state is not empty and if my item is equal to him, I want to reset him by calling resetState()and the empty string
My problem is : I try to replace stateItem.checkedA by something like stateItem.item to avoid repetitions but doesn't work for me, is it possible in react to do that ?
This is what I have :
const [stateBoolean, setStateBoolean] = React.useState({
checkedA: false,
checkedB: false
});
const [stateItem, setStateItem] = React.useState({
checkedA: "",
checkedB: "toto",
checkedC: "onlyHere not in Boolean"
});
const check = (listState) => {
listState.map(item => {
(stateBoolean.checkedA === true || stateItem.checkedA !== "") &&
item === "checkedA"
? (resetChange("checkedA", "stateItem"),
resetChange("checkedA", "stateBoolean"))
: null;
(stateBoolean.checkedB === true || stateItem.checkedB !== "") &&
item === "checkedB"
? (resetChange("checkedB", "stateItem"), resetChange("checkedB", "stateBoolean"))
: null;
stateItem.checkedC !== "" && item === "checkedC"
? resetChange("checkedC", "stateItem")
: null;
});
};
What I expected, but not working:
const checkWanted = (listState) => {
listState.map(item => {
(stateBoolean.item === true || stateItem.item !== "") &&
(item === "checkedB" || item === "checkedA")
? (resetChange(item, "stateItem"), resetChange(item, "stateBoolean"))
: null;
stateItem.checkedEOther !== "" && item === "checkedEOther"
? resetChange(item, "stateItem")
: null;
});
};
Any idea?
Use stateBoolean[item] instead, you can access properties of an object like an array
The function map return a new Array mdn description
If you want to iterate on a array and do something you should use forEach or a for loop.
In order to filter an array on possibly 2 parameters I have written the following code:
filterStudies(searchString?: string) {
if (searchString && !this.selectedModalityType) {
this.studies = this.fullStudyList.filter(function (study) {
return (study.Code.toUpperCase().includes(searchString.toUpperCase())) ||
(study.Description.toUpperCase().includes(searchString.toUpperCase()));
})
} else if (!searchString && this.selectedModalityType) {
console.log(this.selectedModalityType)
this.studies = this.fullStudyList.filter(function (study) {
return (study.ModalityType.Code.toUpperCase() === this.selectedModalityType.toUpperCase())
})
} else if (searchString && this.selectedModalityType) {
this.studies = this.fullStudyList.filter(function (study) {
return (study.Code.toUpperCase().includes(searchString.toUpperCase())) ||
(study.Description.toUpperCase().includes(searchString.toUpperCase())) &&
(study.ModalityType.Code.toUpperCase() === this.selectedModalityType.toUpperCase())
})
}
}
filterStudies(searchString?: string) is called when typing in a textbox that.
The other way of filtering could be by selecting a value from a dropdown box. Achieved by this code:
handleSelection(value:any){
this.selectedModalityType = value;
console.log(value)
this.filterStudies()
}
All works fine until this code is hit:
this.studies = this.fullStudyList.filter(function (study) {
return (study.ModalityType.Code.toUpperCase() === this.selectedModalityType.toUpperCase())
})
Error message : ERROR TypeError: Cannot read property 'selectedModalityType' of undefined, I see it is actually logged in the line before.
What am I missing??
Thanks,
In your funtcion, this is not the same this as the line before.
This will work:
let self = this;
this.studies = this.fullStudyList.filter(function (study) {
return (study.ModalityType.Code.toUpperCase() === self.selectedModalityType.toUpperCase())
})
You can read this to learn more: https://github.com/Microsoft/TypeScript/wiki/%27this%27-in-TypeScript
The this keyword in JavaScript (and thus TypeScript) behaves differently than it does in many other languages. This can be very surprising, especially for users of other languages that have certain intuitions about how this should work.
(...)
Typical symptoms of a lost this context include:
A class field (this.foo) is undefined when some other value was expected