7

I'm trying to read a local json file and parse it into a class that i made which have the same properties. When i try to read from the class, it gives me errors saying the class is null or undefined.

I have a file hall.ts which looks like this:

import {Item} from '../item/item';
export class Hall {
    constructor(public id:number,
                public naam:string,
                public oppervlakte:number,
                public aantalItems:number,
                public itemsMetNodigeActie:number,
                public items:Item[]) {
    }
}

It uses item.ts:

export class Item {
    constructor(public categorie:string,
                public naam:string,
                public productnummer:string,
                public omschrijving:string,
                public laatsteUitgevoerdeActie:Actie,
                public eerstVolgendeActie:Actie) {
    }
}
export class Actie{
    constructor(datum: string,
                type: string,
                omschrijving: string){}
}

The json file, hall1.json, that i'm trying to read from looks like this:

{
  "id": 1,
  "naam": "hall1",
  "oppervlakte": 100,
  "aantalItems": 3,
  "itemsMetNodigeActie": 3,
  "items": [
    {
      "id": 1,
      "categorie": "machine",
      "productnummer": "ADE124e",
      "omschrijving": "print papieren af",
      "laatsteUitgevoerdeActie": {
        "datum": "2015-01-05T00:00:00.000Z",
        "type": "vervanging",
        "omschrijving": "papier vervangen"
      },
      "eerstVolgendeActie": {
        "datum": "2016-01-06T00:00:00.000Z",
        "type": "vervanging",
        "omschrijving": "inkt vervangen"
      }
    }
  ]
}

I'm using a hall.service.ts which tries to read the json file which is locally stored, and returns it in an Hall object. This is the methode for doing that:

public getHall(): Observable<Hall> {
    return this.http.get('app/hall/hall1.json')
        .map((res:Response) => res.json());
}

I use this method in my hallDetail.component.ts

export class HallDetailComponent implements OnInit{
    public hall: Hall;
    constructor(
        private service: HallService
    ){}
    ngOnInit(){
        this.service.getHall().subscribe((hall:Hall) => {
            this.hall = hall;
        })
    }
}

So far it doesn't give me any errors, but when i try to read from the hall object, it sais that it is undefined

@Component({
    template: `
  <div>
    {{hall.naam}}
  </div>
  `
})

Error :

EXCEPTION: TypeError: Cannot read property 'naam' of undefined in [
    {{hall.naam}}
   in HallDetailComponent@1:7]
2
  • did you try logging the result.json() to see if you are actually loading content? Commented Dec 31, 2015 at 14:13
  • 2
    Check out Elvis Operator Commented Dec 31, 2015 at 14:23

1 Answer 1

9

You have to remember that the http.get() call is async. Your template is trying to process hall as an object before it has been resolved by your async http call.

That's why hall is undefined and, therefore, you can't access any properties on it (it does not yet exist).

As Eric mentioned in the comment, try something like this for your template:

@Component({
    template: `
  <div>
    {{hall?.naam}}  <!-- note the added ? -->
  </div>
  `
})

That will make the reference to naam on hall null safe.

Update:

For the sake of completeness, I'll point out that you can actually use *ngIf for this as well, though the null safe check makes for a cleaner looking template.

@Component({
    template: `
  <div *ngIf="hall"> <!-- note the added *ngIf -->
    {{hall.naam}}
  </div>
  `
})
Sign up to request clarification or add additional context in comments.

2 Comments

Someone mentioned in another comment on SO that you can get better performance with something like <div *ngIf="thing">{{thing}}</div>, because it will only render it if that thing is there.
@josh That wouldn't surprise me. Using ngIf in Angular 1 was much more performant than ngHide and ngShow for similar reasons. But the bindings are much faster, in theory, in ng2, so if you didn't have 100 of these null safe checks in a view it probably wouldn't make an appreciable difference.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.