Edit: It looks like my main problem now is that I can\'t seem to display async data from an object. I have a promise containing the data object, and when I use
You can also use pluck from rxjs/observable:
{{ user.pluck("name") | async }}
Pluck Returns an Observable containing the value of a specified nested property from all elements in the Observable sequence. If a property can't be resolved, it will return undefined for that value.
There's nothing wrong with the accepted answer above. But it becomes a hassle to append | async?
when we need to display many properties of the object. The more convenient solution is as follows:
<div *ngIf="data | async as localData">
<div> {{ localData.name }} </div>
<div> {{ localData.property1 }} </div>
<div> {{ localData.property2 }} </div>
</div>
The OP asked for promises but in case people are using Observable
s, adapting @user2884505's answer, since pluck
isn't directly available on observables as a method in recent versions of RxJS, you may have something like this :
import { Pipe, PipeTransform } from '@angular/core';
import { Observable } from 'rxjs';
import { pluck } from 'rxjs/operators';
@Pipe({
name: 'asyncKey',
pure: false
})
export class AsyncKeyPipe implements PipeTransform {
private observable: Observable<Object>;
private result: Object;
transform(value: any, ...args: any[]): any {
if (!this.observable) {
this.observable = value.pipe(pluck(...args));
this.observable.subscribe(r => this.result = r);
}
return this.result;
}
}
And then, you can use it, even for nested keys :
{{ user$ | asyncKey: 'address' : 'street' }}
So I ended up writing my own asynchronous key pipe. Huge thanks to Simon for helping guide me here.
import {Pipe} from 'angular2/core';
@Pipe({
name: 'key',
pure: false
})
export class KeyPipe {
private fetchedPromise: Promise<Object>;
private result: string;
transform(value: Promise<Object>, args: string[]) {
if(!this.fetchedPromise) {
this.fetchedPromise = value
.then((obj) => this.result = obj[args[0]] );
}
return this.result;
}
}
Usage:
<h2>{{ data | key: 'Name' }}</h2>
Someone please comment if Angular has its own functions for resolving a key from an asynchronous object.
If you work with Observable you can display data like this way:
<div *ngIf="data | async; let _data">
<h3>{{_data.name}}</h3>
</div>
or
<h3>{{(data | async).name}}</h3>
You do not need any special pipe. Angular 2 suppport optional field. You just need to add ? in your object
{{ (data | async)?.name }}
or
{{(name | async)?}}