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
{{ data | async }}
it will display
[object Object]
The issue is, I want to be able to display all the different attributes; ie, Name, Symbol, etc. In Angular 1, I would just use
{{ data.Name | async }}
but that doesn't work here, since the async pipe tries to resolve the data.Name promise, which doesn't exist. I want to resolve the data promise and then display the Name key from it. At the moment, I'm working on creating my own pipe to display a key from an async object, but I'm wondering if there's a built-in Angular 2 pipe or function to handle this!
I've created a StockService class that returns a Promise containing an object to my StockInfo class, which contains the HTML to be displayed. I want to display the name of this object in my HTML, but I can't seem to get it to display.
In my StockInfo constructor:
this.stock.getStockData(this.ticker, http).then(function(val) {
this.data = val;
this.name = new Promise<string>(function(resolve) {
resolve(this.data.Name);
});
});
where this.stock is the StockService object.
In my HTML:
<h2>{{name | async}}</h2>
I've tried a number of different arrangements before settling on this one. I want the StockService class to handle the data fetching and the StockInfo class to handle the display. In Angular 1, I would create a factory for fetching data and handle the data processing in the controller, but I'm not quite sure how to go about this in Angular 2.
Is there a way to get it to display, or are there better ways to design my code that I should look into? Thanks!
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)?}}
There's nothing wrong with the accepted answer above. But it becomes a hassle to append | async?
| 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>
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>
I think you are making this too complex, and just need to do something like this.
this.name =
this.stock.getStockData(this.ticker, http)
.then( val => val.Name )
and
<h2>{{name.Name | async}}</h2>
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.
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' }}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.