简体   繁体   中英

Cannot read property 'version' of undefined angular2

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM