Is there something like a Safe Navigation Operator that can be used on Arrays?
Asked Answered
D

4

25

I have used Safe Navigation Operator for Objects to load on Asynchronous calls and it is pretty amazing. I thought I could reproduce the same for Arrays but it displays a template parse error in my Angular code. I know *ngIf is an alternative solution, but is there a more simpler(by code) way just like the Safe Navigation Operator?

<div class="mock">
   <h5>{{data?.title}}</h5>  //This works
   <h6>{{data?.body}}</h6>  //This works
   <h6>{{simpleData?[0]}}</h6>  // This is what I tried to implement    
</div>
Dragonfly answered 20/6, 2017 at 7:31 Comment(0)
B
12

is there a more simpler(by code) way just like the Safe Navigation Operator?

There is ternary operator.

condition ? expr1 : expr2

<h6>{{simpleData?simpleData[0]:''}}</h6>   
Batho answered 20/6, 2017 at 7:34 Comment(2)
This tends to become very unreadable when you have rather complex, deep data: ((a?.b||[])[13]?.c||[])[7] instead of a?.b?.[13]?.c?.[7] in modern ECMAscriptTamalatamale
While not exactly Angular-specific, you could also use lodash to safely retrieve more deeply nested objects. e.g. get myData() { return _.get(this.thing, 'a[0].b.c'); } lodash.com/docs/4.17.15#getProbabilism
D
40

Is there something like a Safe Navigation Operator that can be used on Arrays?

Yes, what you are looking for is known as the Optional Chaining operator (JavaScript / TypeScript).

The syntax shown in the MDN JavaScript documentation is:

obj.val?.prop
obj.val?.[expr]
obj.arr?.[index]
obj.func?.(args)

So, to achieve what you want, you need to change your example from:

<h6>{{simpleData?[0]}}</h6>

To:

<h6>{{simpleData?.[0]}}</h6>
                 ^

Also see How to use optional chaining with array in Typescript?.

Dias answered 29/1, 2021 at 14:35 Comment(1)
for anyone looking this is the latest and this can be used in component logic as well.Stokes
B
12

is there a more simpler(by code) way just like the Safe Navigation Operator?

There is ternary operator.

condition ? expr1 : expr2

<h6>{{simpleData?simpleData[0]:''}}</h6>   
Batho answered 20/6, 2017 at 7:34 Comment(2)
This tends to become very unreadable when you have rather complex, deep data: ((a?.b||[])[13]?.c||[])[7] instead of a?.b?.[13]?.c?.[7] in modern ECMAscriptTamalatamale
While not exactly Angular-specific, you could also use lodash to safely retrieve more deeply nested objects. e.g. get myData() { return _.get(this.thing, 'a[0].b.c'); } lodash.com/docs/4.17.15#getProbabilism
C
8

Of cause it's a matter of taste, but in such cases I tend to use a shorter approach:

<h6>{{(simpleData || [])[0]}}</h6>
Coppinger answered 11/11, 2019 at 11:35 Comment(3)
but it is empty array, so accessing first element will fail anyway?Buckler
No it won't. Reading non-existing element returns undefined which is translated to an empty result by Angular.Coppinger
Some might consider using the Nullish Coalescing operator (??) to now be considered a better practice: (simpleData ?? [])[0]. That said, the now available Optional Chaining operator (?.) offers a more direct solution to the stated question.Dias
T
0

The other answers amount to the same thing, but I find foo && foo[0] to be the most readable. The right side of the logical-and operator won't be evaluated if the left side is falsy, so you safely get undefined (or I guess null, if you don't believe Douglas Crockford.) with minimal extra characters.

For that matter, you asked for a "simpler" solution, but actually *ngIf is probably correct for the use case you gave. If you use any of the answers here, you'll wind up with an empty h6 tag that you didn't need. If you make the tag itself conditional, you can just put foo[0] in the handlebars and be confident that it won't be evaluated when foo is still undefined, plus you never pollute the page with an empty tag.

Theatheaceous answered 24/2, 2020 at 14:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.