3

I would like to call a typescript property from angular2 template. I can't do that if I call the property of an object in a loop. If there is no loop, the code works fine.

Calling method from a Angular 2 class inside template this question addresses the problem if there is no loop.

Please find the Plunker here .

import {Component} from '@angular/core'

export class User {
  id: number;
  mail: string;
  created_at: string;
  first_name: string;
  last_name: string;
  deleted_at: any;

 // if I call {{user.name}} nothing gets printed.
 get name() {
    return "My name is:" + this.first_name;
  }
}

@Component({
  selector: 'my-app',
  template: `
    <ion-list *ngFor="let user of users">
        <div>{{user.first_name}}</div>
    </ion-list>
  `
})
export class App {
  users: User[];
  constructor() {
    this.users = [ {first_name:"Jagan"}, {first_name:"Nath"}  ];
  }
}

Update

Here is a piece of code. Both working and not working version is given below.

//our root app component
import {Component, Input} from '@angular/core'
import { MyComponent } from './my-component';


export class User {

  first_name : string;

  get name() {
    return "Name:" + this.first_name;
  }
}


@Component({
  selector: 'my-app',
  template: `
    <div>
       {{user.first_name}}
    </div>
  `,
  directives: [ MyComponent ]
})   

export class App {

  constructor() {
    let str = "{ \"first_name\" : \"Jagan\" }";
    this.user = JSON.parse(str) as User;
  }
}

// This does not work.

 /* @Component({
      selector: 'my-app',
      template: `
        <div>
           {{user.name}}
        </div>
      `,
      directives: [ MyComponent ]
    })
    */
Community
  • 1
  • 1
Jagannath
  • 3,995
  • 26
  • 30

2 Answers2

5

UPDATE

In your updated code you are just telling TypeScript that whatever JSON object you have now should be considered as a User object. TypeScript will happily parse that for you, but in runtime you don't actually have a User object, as demonstrated by the fact that you can't access the name method. You can inspect the object yourself by just printing it to console: console.log(this.user). You will see it prints Object {first_name: "Jagan"}. That is clearly not a User object.

I would suggest to create a constructor on User that accepts a JSON parameter and have the User object configure itself with this JSON. I have created a Plunker for you to see the idea in action: Plunker - updated

The User will get a constructor that accepts a JSON config (you could even type that if you want):

constructor(config: any) {
  this.first_name = config.first_name;
}

And when constructing the User, you pass along the configuration in its constructor:

let obj = { first_name: 'Jagan' };
this.user = new User(obj);

ORIGINAL

When you create a new User you should use a constructor to set the parameters of the new User object. In the current situation you are just pushing some new objects (not even User objects) onto the users array by typing {first_name: "name"}. You can check that out in your current code by printing the users array to your console (that is: console.log(users)).

I have created a Plunker with a constructor on User: Plunker.

The User will get a constructor:

 constructor(first_name: string) {
   this.first_name = first_name;
 }

And calling new User now expects a new argument, first_name:

this.users = [ new User("Jagan"), new User("Nath")  ];
Sjoerd
  • 1,255
  • 1
  • 11
  • 15
  • Nope, I missed that, but I updated the answer now. The idea is still the same: use a constructor in User. – Sjoerd Jun 09 '16 at 06:20
  • Looks like this works. I tested my plunker sample. It worked there. Most likely it will work in my application. Will test it once I go home. For time being, I accepted the answer. I understood the problem now. – Jagannath Jun 09 '16 at 07:09
  • The code worked. But forgot to let you know here. Thanks. – Jagannath Jul 29 '16 at 23:11
3

This code:

this.users = [ {first_name:"Jagan"}, {first_name:"Nath"}  ];

typechecks because typescript is structural (more : https://basarat.gitbooks.io/typescript/content/docs/why-typescript.html) however it does not creates User. You need to new User to get the get name property

basarat
  • 261,912
  • 58
  • 460
  • 511
  • OK. I created that and now it calls the method / property. But I get this `My name is:undefined My name is:undefined` – Jagannath Jun 09 '16 at 01:52
  • @Jagannath you've forgotten to set `first_name` – basarat Jun 09 '16 at 01:59
  • I am not sure. The actual scenario is a bit different though. I get data through a service in a JSON format. I parse it to an Object and then I bind them to the template. I can't set the members explicitly. – Jagannath Jun 09 '16 at 03:55