I have the following the condition:
useEffect(() => {
const hasFalsyValue = (
dropdownValue === undefined
|| dropdownValue === null
);
if (hasFalsyValue && !onChangeText) {
return;
}
onChangeText(dropdownValue);
}, [
dropdownValue,
onChangeText,
inputProps,
]);
If hasFalsyValue is true, then, the effect will return right away. But TS is yelling on me saying the dropdownValue can still be undefined
If I extract the conditions from the constant and put it inside the conditional parenthesis, it will work
If hasFalsyValue is true, then, the effect will return right away.
No - only when hasFalsyValue is true and onChangeText is falsy. You might have meant
const hasFalsyValue = (dropdownValue === undefined || dropdownValue === null);
if (hasFalsyValue || !onChangeText) {
return;
}
onChangeText(dropdownValue);
or
const hasFalsyValue = (dropdownValue === undefined || dropdownValue === null);
if (!hasFalsyValue && onChangeText) {
onChangeText(dropdownValue);
}
Btw I'd recommend to shorten this to
if (dropdownValue != null) {
onChangeText?(dropdownValue);
}
That's almost OK. you misused && and TypeScript is not so smart to pick up variable, so this should work:
#1 Define guard
function isDefined<T>(v: T|undefined): v is T {
return v!= null
}
#2 use it
if (!isDefined(dropdownValue) || !onChangeText) {
return;
}
onChangeText(dropdownValue);
Related
So I'm trying to check for an undefined object out of multiple ones and then do something with that specific one. This code below works but I can imagine that there's a better way than just using else if 20 times in a row.
if (duelswins === undefined) {
document.getElementById('duels_wins').style.display = 'none'
} else if (duelslosses === undefined) {
document.getElementById('duels_losses').style.display = 'none'
} else if (duelskills === undefined) {
document.getElementById('duels_kills').style.display = 'none'
} else if (duelsdeaths === undefined) {
document.getElementById('duels_deaths').style.display = 'none'
} else if (duelsgoals === undefined) {
document.getElementById('duels_goals').style.display = 'none'
} else if (duelskdr === undefined) {
document.getElementById('duels_kdr').style.display = 'none'
} else if (duelswlr === undefined) {
document.getElementById('duels_wlr').style.display = 'none'
} else if (duelsgwr === undefined) {
document.getElementById('duels_gwr').style.display = 'none'
}
There can be multiple ones of those being undefined but it could also be also none of them.
This is just an example, I'm mostly interested if there's and alternative for using so many if statements just for checking basically the same thing over and over again.
Instead of using individual variables you can put these values into an object and then loop over the keys/values. I'm not sure what your requirements are exactly but this might be a step in the right direction:
const data = {
duels_wins: undefined,
duels_losses: 123,
duels_deaths: undefined,
// ...
};
Object.entries(data).forEach(([key, value]) => {
if (value === undefined) {
document.getElementById(key).style.display = 'none';
}
});
<div id="duels_wins">duels_wins</div>
<div id="duels_losses">duels_losses</div>
<div id="duels_deaths">duels_deaths</div>
function test(val) {
const hasError = val ?? true;
if (hasError) {
//error handling...
} else {
//do something...
}
}
test(null) //error handling...
test(undefined) //error handling...
test('text') //error handling...
test(true) //error handling...
like this case i want to filter 'null' and 'undefined'
but it`s work every truthy value.
So i have only one option...
const hasError = (val === undefined || val === null);
Is there any way of use nullish operator in this case?
and when nullish operator is used generally?
thank you
If you're sure that
const hasError = (val === undefined || val === null);
captures the logic you want, then the problem is that
const hasError = val ?? true;
gives you the opposite of that if you're subsequently going to use that flag in an if expression. You'd really want to follow with
if (hasError !== true)
which is really confusing (to me). Instead, you can think of the ?? operator giving you the opposite:
const noError = val ?? true;
if (!noError)
which makes a little more sense. Personally I'd use
const hasError = val == null;
or just perform the test in the if directly.
For example, in iOS Swift, I can do something like this:
if (self.user?.company?.pic?.phoneNumber != null) { doSomething() }
Without the need to:
if (self.user != null && self.user!.company != null && self.user!.company!.pic != null && self.user!.company!.pic!.phoneNumber != null) { doSomething() }
In ReactNative (or Javascript), I found out that if an object is undefined, I can't check for the existence of the variable inside of it, so I have to check first whether the object is undefined or not, only then I can safely check whether the variable inside of it undefined or not.
if (typeof this.state.user !== "undefined" && typeof this.state.user.company !== "undefined" && typeof this.state.user.company.pic !== "undefined" && typeof this.state.user.company.pic.phoneNumber !== undefined) { this.doSomething() }
How can I turn this into just:
if (typeof this.state.user.company.pic.phoneNumber !== "undefined") { this.doSomething() }
or something similar?
Thanks.
Currently, optional chaining is a stage 3 draft, and so, you may be able to do it in the future.
EDIT:
Optional chaining will now be part of ES2020, and so you'll be able to do the following:
if (self.user?.company?.pic?.phoneNumber !== undefined) {
doSomething(); // phoneNumber exists
}
With that being said, it still has very limited browser support.
So, for the time being, you could instead create a function which recursively finds each object from a list of properties like so:
const optional_chain = (obj, [key, ...props]) =>
obj !== undefined && key ? optional_chain(obj[key], props) : obj;
const user = {
company: {
pic: {
phoneNumber: 1
}
}
}
console.log(optional_chain(user, ['company', 'pic', 'phoneNumber'])); // 1
console.log(optional_chain(user, ['company', 'pic', 'phoneNumber', 'x'])); // undefined
console.log(optional_chain(user, ['company', 'picture', 'phoneNumber'])); // undefined
console.log(optional_chain(user, ['x', 'picture', 'phoneNumber'])); // undefined
In your case, the usage would be as so:
if (optional_chain(self.user, ['company', 'pic', 'phoneNumber']) !== undefined) {
doSomething();
}
If you can’t use optional chaining which is still a proposal but available via babel plugin you could use a recursive utility function to test for the presence of each path segment:
const pluck = (item, path) => {
const [, part, rest] = /^([^.]+)\.*(.*)/.exec(path) || [];
if (!part) {
return null;
}
const o = (item || {})[part];
if (o == null) {
return null;
}
return rest.length ? pluck(o, rest) : o;
};
if (pluck(this.state, ‘user.company.pic.phoneNumber’)) {
doSomething();
}
Given the following snippet:
let a;
if (obj === undefined ||
obj.prop === undefined ||
(a = await getResultFromLongOperation(obj.prop)) === undefined) {
// Do things to handle the case where the params were wrong and throw an error
}
console.log(a); // a is not undefined
I would like to avoid assigning the value of a inside the if.
But I also don't want to make multiple calls to getResultFromLongOperation and I don't want to duplicate the "things to handle the case where the params where wrong".
How can I refactor this?
Only solution I found was to refactor as such:
function doThingsToHandleTheCaseTheParamsAreWrong() {
// Do things to handle the case where the params were wrong and throw an error
}
if (obj === undefined ||
obj.prop === undefined) {
doThingsToHandleTheCaseTheParamsAreWrong();
}
let a = getResultFromLongOperation(obj.prop);
if (a === undefined) {
doThingsToHandleTheCaseTheParamsAreWrong();
}
console.log(a); // a is not undefined
Is this really better?
Would this construct work in your case:
const a = getResultFromLongOperation(obj.prop) || doThingsToHandleTheCaseTheParamsAreWrong();
Depending on if a can return other falsy values that undefined.
const tmpA = getResultFromLongOperation(obj.prop);
const a = tmpA !== undefined ? tempA : doThingsToHandleTheCaseTheParamsAreWrong();
I'm beginner on JavaScript and AngularJS. So I encounter following code from Adam Freeman books
var selectedCategory = null;
...
$scope.categoryFilterFn = function(product) {
return selectedCategory == null ||
product.category === selectedCategory;
};
I get confused by the return statement above, can you guys re-write the code above with clear code (no shorthand).
Thanks.
This is a short-hand form of returning a boolean value. Look closely:
return selectedCategory == null || product.category === selectedCategory;
Here, return statement has two expressions:
selectedCategory == null
product.category === selectedCategory
When the method returns, it will evaluate these two expressions separately. Consider yout selectedCategory is null, and the product.category is equal to selectedCategory then the statement is
return true || true;
which will eventually simplifies to
return true; // (true || true) = true
Likewise, you can think of this expressions return value by substituting values and evaluate them separately.
Longer version for this is:
if (selectedCategory == null || product.category == selectedCategory) {
return true;
} else {
return false;
}
The return statement could be re-written easily as an if() block as follows:
$scope.categoryFilterFn = function(product) {
if( selectedCategory == null || product.category === selectedCategory )
{
return true;
}
return false;
};
Essentially, the return is going to return true if either of the specified conditions is true. Otherwise, it will return false.