TS Code
image = this.selectedItem.image.url || null;
The Error
TypeError: Cannot read property 'url' of null
My question is, why isn't the || null kicking in instead of it throwing a type error?
TS Code
image = this.selectedItem.image.url || null;
The Error
TypeError: Cannot read property 'url' of null
My question is, why isn't the || null kicking in instead of it throwing a type error?
Share Improve this question asked Oct 18, 2017 at 14:28 mls3590712mls3590712 8201 gold badge9 silver badges20 bronze badges6 Answers
Reset to default 6The shortest option you have is:
image = this.selectedItem && this.selectedItem.image && this.selectedItem.image.url || null;
If any of the &&
fails, you'll get null
instead, but you have to check every "level" of the object you're trying to access.
This works because the &&
takes priority over ||
for order of operation. The above statement is similar to:
x = (((a.b) && (a.b.c)) && (a.b.c.url)) || null;
What you had, on the other hand, was similar to:
x = (a.b.c.url) || null;
You can't get url
if a.b
does not have a property c
. That's what the error was thrown on, and that's not something the "or" at the end can catch.
I think you're confused about what "short-circuit" means. Boolean operators are evaluated from left to right (&&
before ||
but left-to-right otherwise) until the result is either definitely falsy or truthy, and then it stops without evaluating anything else. In your case, the error occurs while this.selectedItem.image.url
is being evaluated, and the ||
operator is never reached.
JavaScript lacks a null/undefined-coalescing operator such as the Elvis operator "?.
", which would let you do something like this.selectedItem?.image?.url
to prevent dereferencing undefined
values.
Instead, you need to check each possible nested property for existence, if it is possible for them to be undefined:
image = (this.selectedItem && this.selectedItem.image && this.selectedItem.image.url) || null;
(I'm sure other answers have mentioned something like this... ah, yes, @Cerbrus has it) This is now short-circuiting in a way that helps you. As soon as one of those items is falsy, the whole parenthesized term evaluates as falsy without throwing an error. Then you get falsy-|| null
which bees null
, as you want.
Hope that helps; good luck!
You are checking this.selectedItem.image.url
, but for that to be possible, you need to make sure that this.selectedItem
and this.selectedItem.image
exist first.
You could try the following:
image = this.selectedItem && this.selectedItem.image ? this.selectedItem.image.url || null : null;
You need to check also if the field image
exists I think. Try to use ternary operator instead:
image = this.selectedItem.image ? this.selectedItem.image.url : null;
Because the error occurred when this.selectedItem.image.url
itself was evaluated. You can fix it this way:
this.selectedItem.image = this.selectedItem.image || {}
image = this.selectedItem.image.url || null;
TypeScript:
image = this?.selectedItem?.image?.url || null;
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745453496a4628378.html
评论列表(0条)