I am having a hard time using a async object in a html composition.
Here is my model:
export class Version {
isGood: boolean;
constructor(isGood: boolean) {
this.isGood= isGood;
}
}
This model is called by a component as follows:
@Injectable()
export class MyComponent {
public version: Version;
constructor(private _myService: VersionService) {}
getVersion(): void {
// async service that gets the versions
this._myService.getVersion().subscribe(
data => this.version= data,
error=> console.log(error),
() => console.log("getting all items complete")
);
}
}
My template references to the version variable as follows:
<button (click)="getVersion()">Get Version</button>
<hr>
<p style="color:red">{{error}}</p>
<h1>Version</h1>
<p>{{version.isGood}}</p>
However, I get an exception:
Cannot read property 'isGood' of undefined
From scavenging the internet, I see that my problem is because the version object is null. If I do something like:
<p>{{version | json}}</p>
I can see the correct version
If I do something like
<p>{{version.isGood | async}}</p>
I see nothing
If I edit MyComponent, and set
public version: Version = new Version();
I can execute the .isGood property fetch, but it is always empty.
Is there a different way I am supposed to load a property if I am using it in an asynchronous manner?
Use the ?
operator or use an *ngIf
.
<p>{{version?.isGood}}</p>
<p *ngIf="version">{{version.isGood}}</p>
Try this:
<p>{{version?.isGood}}</p>
This tells Angular to protect against version.isGood being undefined or null until you click and fetch the data for version through your service.
First me correct you. @Injectable() makes a normal typescript class as injectable service where you can share data.
To make a component you need to use @Component decoratore.
The process of data sharing between component and within the application is to create a service and add that as provides in module. And then its singleton object will available everyshere.
//module
import {NgModule} from '@angular/core';
import {YourService} from "./services/your-service";
@NgModule({
imports: [
BrowserModule
],
declarations: [
AppComponent
],
providers: [
YouService
],
bootstrap: [AppComponent]
})
export class AppModule {
}
//this is your component
import {Component} from '@angular/core';
import {YourService} from "../../services/your-service";
@Component({
selector: 'component-app',
templateUrl: '../../views/app.component.html',
})
export class HeaderComponent {
constructor(public yourService: YourService) {
}
}
//your service
import {Injectable} from "@angular/core";
@Injectable()
export class YourService {
private _message: string = 'initial message';
private _style: string = 'success';
get message(): string {
return this._message;
}
set message(value: string) {
this._message += value;
}
get style(): string {
return this._style;
}
set style(value: string) {
this._style = value;
}
}
//finally your view
<div class="row">
<div [class]=""><h1>{{swapService.message}}</h1></div>
</div>
Observable Data services.
@Injectable()
export class MyComponent {
public version = new ReplaySubject<Version>();
constructor(private _myService: VersionService) {}
init(): void {
// async service that gets the versions
this._myService.getVersion().subscribe(
data => this.version.next(data),
error=> console.log(error),
() => console.log("getting all items complete")
);
}
getVersion(): void {
this.version.asObservable();
}
}
In the template
<button (click)="init()">Get Version</button>
<hr>
<p style="color:red">{{error}}</p>
<h1>Version</h1>
<p>{{(version |async)?.isGood}}</p>
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.