Here is the state of my App:
const [state, setState] = useState({
priceType: 0,
recurrenceType: 0,
start_date: '',
end_date: '',
minCapacity: 0,
maxCapacity: 0,
price: 0,
min: 0,
max: 0,
days: []
});
Here is the code of condition in which I am trying to achive, if any property of the state has null value then return true otherwise return false.
const isNullish = Object.values(state).every(value => {
if (value==='' && value===0 && value === []) {
return true;
}
return false;
});
console.log(isNullish)
console.log(state)
But the chalenge is whenever I execute that code in my app it returns false although the properties has no value.Below is the console output of above code:
false
SpecialPrice.jsx:124 {priceType: 0, recurrenceType: 0, start_date: '', end_date: '',
minCapacity: 0, …}
days: []
end_date: ""
max: 0maxCapacity: 0
min: 0
minCapacity: 0
price: 0
priceType: 0
recurrenceType: 0
start_date: ""
[[Prototype]]: Object
SpecialPrice.jsx:129 []
For better understanding I have attached a screenshot here:
CodePudding user response:
First problem:
The logic is asserting a value is equal to three different other values with the logical AND (&&
), which will just about always be false.
value === '' && value === 0 && value === []
A value can never be strictly equal to a string ''
and a number 0
, and an empty array []
.
You could assert on the inverse of each though, checking for inequality.
value !== '' && value !== 0 && value !== []
Second problem:
The last condition, value === []
, even if value
currently had the value []
, [] === []
always evaluates false, they are two object references and these can never be strictly equal.
const value = [];
console.log(value === []); // false
console.log([] === []); // false
Solution
Use logical OR (||
) instead to check each condition.
The final condition should first check if the value is an array and then check for 0 length, or use the Optional Chaining operator (basically to guard against undefined value
values).
Example:
const isNullish = Object.values(state).every((value) => {
return value === "" || value === 0 || (Array.isArray(value) && !value.length);
});
or
const isNullish = Object.values(state).every((value) => {
return value === "" || value === 0 || !value?.length;
});
or since both ''
and 0
are considered falsey values you can further simplify the conditionals.
const isNullish = Object.values(state).every((value) => {
return !value || !value.length;
});
Falsey values include false
, 0
, -0
, 0n
, ""
(and other empty strings), null
, undefined
, NaN
.
const state = {
priceType: 0,
recurrenceType: 0,
start_date: "",
end_date: "",
minCapacity: 0,
maxCapacity: 0,
price: 0,
min: 0,
max: 0,
days: [],
days2: undefined
};
const state2 = {
priceType: 0,
recurrenceType: 0,
start_date: "",
end_date: "",
minCapacity: 0,
maxCapacity: 0,
price: 0,
min: 0,
max: 0,
days: [3],
days2: undefined
};
const isNullish = arr => Object.values(arr).every((value) => {
return !value || !value.length;
});
console.log(isNullish(state)); // true
console.log(isNullish(state2)); // false
CodePudding user response:
.every
is in this case not the right approach. With .every you check if every value is 0 or []. In your case not every value is 0 or [].
I would suggest you use .some
Something like this:
const isNullish = Object.values(state).some(x => x === 0 || x === [] || x === '');