Basil Bear
Basil Bear

Reputation: 463

Why can't I access my angular2 class property

I'm new to Angular 2 and thoroughly puzzled at this moment.

I am loading a component which retrieves data from service (in JSON format), and I am apparently NOT being successful when it comes to setting a property in my class which I want to represent that data.

I can however (with debugger) see the returned data and alert() it. I think that I am setting the property, but the template reports an error that it does not understand the property.

So, I have this:

import { Response } from '@angular/http';
import { Location } from '@angular/common';
import { ActivatedRoute, Params } from '@angular/router';
import { Component, Input, OnInit } from '@angular/core';
import 'rxjs/add/operator/switchMap';
import { SiteService } from './site.service';
import { Site } from './site';

@Component({
    moduleId: module.id,
    selector: 'site-detail',
    templateUrl: 'site-detail.component.html'
})
export class SiteDetailComponent implements OnInit {

    public site: Site;  // **Site is an interface**

    constructor(
        private siteService: SiteService,
        private route: ActivatedRoute,
        private location: Location
    ) { }

    // getSite(): void {
    ngOnInit(): void {
        this.route.params
            .switchMap((params: Params) => this.siteService.getSite(params['id']))
            .subscribe((data: Response) => {
                this.site = data[0];
                alert(this.site.sitex_invoiceAccount); ** ALL LOOKS GOOD AT THIS POINT **
            })
    }
}

The alert() happily reports the correct invoiceAccount value, suggesting to me that I have assigned the data to my property site.

However, the template is not convinced and this snippet:

 <div class="form-group">
    <label for="xxxx">Site ID</label>
    <input type="text" class="form-control" [value]="site.sitex_invoiceAccount">
 </div>

tells me:

EXCEPTION: Uncaught (in promise): Error: Error in http://localhost:3000/app/site-detail.component.html:5:52 caused by: Cannot read property 'sitex_invoiceAccount' of undefined TypeError: Cannot read property 'sitex_invoiceAccount' of undefined

Can anyone to tell me the error that I am committing please?

Thank you kind people.

Upvotes: 1

Views: 733

Answers (2)

Stefan Svrkota
Stefan Svrkota

Reputation: 50633

That's because you are getting data using HTTP call which is an asynchronous operation and you are trying to display data before you get it from server. Basically, before your site variable is filled with data you get from HTTP call, it is undefined and that's why you are getting this error. You can use safe navigation operator (?) in your template to protect it until data arrive:

<div class="form-group">
    <label for="xxxx">Site ID</label>
    <input type="text" class="form-control" [value]="site?.sitex_invoiceAccount">
</div>

You can also use NgIf directive to render that part of your template only after you populate sata variable with data:

<div *ngIf="site" class="form-group">
    <label for="xxxx">Site ID</label>
    <input type="text" class="form-control" [value]="site.sitex_invoiceAccount">
</div>

Upvotes: 2

Petr Adam
Petr Adam

Reputation: 1437

Try to initialize the this.site property earlier, for example in constructor like:

this.site = {}

The problem is, that in time of evaluation of site.sitex_invoiceAccount in your template, site is really undefined. It happens earlier, then your subscribe method finishes.

Upvotes: 2

Related Questions