5

When using an *ngIf, you can do something like *ngIf = (value$ | async).property as prop and then use prop throughout your code without needing to repeat the long (value$ | async).property each time. However, this only works if (value$ | async).property is a truthy value - and not if it is zero for instance.

My question is - how can I still reap the benefits of as but still have the element show if the value is falsy? Or better yet, is there a way to use as outside of an *ngIf or the like?

PMO1948
  • 2,210
  • 11
  • 34
  • You can define a property in your `component.ts` that you could use in your code. That seems to me the best way of doing so. It's not really intended (and I don't think it's possible) to define prop outside of the `*ngIf` scope. However, what's the point of using `prop` outside of the `*ngIf` scope if you know it has no value? You can always define a `*ngIf="(value | async) as prop; else noProp"` and assign `#noProp` to a `ng-template` element somewhere in your component's template. – Ruben Szekér Nov 18 '20 at 07:26
  • Thanks, but if I define it in my component then I need to subscribe to the observable, as opposed to taking advantage of the async pipe. And I want to show the falsey value since in this case it is an enum. I still want to show the first value, I just want a way to shortcut the access to the property. If there is no solution, I'll just repeat the (value$ | async).property in all the places I need it within the element – PMO1948 Nov 18 '20 at 07:44

2 Answers2

2

PMO1948, "the trick" is create an object, credits to Yury Katkov

<div *ngIf="{values: (value$ | async)} as prop">
    ..inside use, e.g.
    {{prop.values?.property}}
    <div *ngIf="!prop.values">
        the observable return nothing
    </div>
</div>

If "value$ |async" return nothing, the *ngIf exist anyway

Sample Demo

Owen Kelvin
  • 14,054
  • 10
  • 41
  • 74
Eliseo
  • 50,109
  • 4
  • 29
  • 67
  • If I did that, I would still need to use `prop.values.property` as opposed to the direct `prop` I can use otherwise. So really I have just changed it from `(value$ | async).property` to `prop.values.property` which does not really shorten it at all – PMO1948 Nov 18 '20 at 09:00
  • There is also a syntax error in your code - there is a closing `}` with no opening one – PMO1948 Nov 18 '20 at 09:01
  • thanks @OwenKelvin to correct and thanks PMO1948 to the comment – Eliseo Nov 18 '20 at 09:45
0

Below is another trick you can implement using ||

<div *ngIf="(value$ | async) || {}  as prop">
    ..inside use, e.g.
    {{prop.property}}
    <div *ngIf="!prop.property">
        the observable return nothing
    </div>
</div>

See Demo Here

Update

Came across ngrxLet Structural Directive and this looks like an interesting solution

The *ngrxLet directive serves a convenient way of binding observables to a view context (a dom element scope) The *ngrxLet directive is provided through the ReactiveComponentModule.`

import { NgModule } from '@angular/core';
import { ReactiveComponentModule } from '@ngrx/component';

@NgModule({
  imports: [
    // other imports
    ReactiveComponentModule
  ]
})
export class MyFeatureModule {}

With the above you can use it

<div  *ngrxLet="value$ as prop">
    ..inside use, e.g.
    {{prop.property}}
    <div *ngIf="!prop.property">
        the observable return nothing
    </div>
</div>
Owen Kelvin
  • 14,054
  • 10
  • 41
  • 74