30

I have a angular 2 application that has a class called User. This user has a attribute called deleted_at that is either null or contains a datetime, obviously the user is deleted if the deleted_at property isn't null. This is how my user.ts file looks:

User.ts

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

    name() {
        if (this.deleted_at === null) {
            return this.first_name;
        } else {
            return 'DELETED';
        }
    }
}

Now I expected that I could just call name in my template with a simple line:

{{ user.name }}

This however returns nothing, how can you call certain functions in the angular 2 template? Or isn't this allowed?

Edit: to clear stuff up a bit, this is a class User that I am using in my component user-list.component.ts, multiple users are handled in this component.

AlexElin
  • 1,044
  • 14
  • 23
hY8vVpf3tyR57Xib
  • 3,574
  • 8
  • 41
  • 86

2 Answers2

22

Either you call the method like this:

{{user.name()}} // instead of {{user.name}}

For this approach you need to be aware that you will lose the execution context (this). See this question for more details:

Or you define your method as a getter so you can use user.name in your template:

get name() {
  if (this.deleted_at === null) {
    return this.first_name;
  } else {
    return 'DELETED';
  }
}
Thierry Templier
  • 198,364
  • 44
  • 396
  • 360
  • 1
    Thanks for your answers, I'm still not there yet though. When I define the getter like you suggested I get a TS error that says: '=' expected, do you know if there is something wrong in the syntax? – hY8vVpf3tyR57Xib May 23 '16 at 08:31
  • Mum strange. See this plunkr: https://plnkr.co/edit/Twhqy3uKbvALwTrjJh0j?p=preview. It works for me. Any difference with what you tried? – Thierry Templier May 23 '16 at 08:57
  • Ah the typescript error was just a syntax problem. The main difference with your plunker and my example is that in my example I loop over a list of users in my template with: *ngFor="let user of users", and for each entry I call user.name. This returns an empty string, could that be because the template doesn't recognise that this is a User class object? – hY8vVpf3tyR57Xib May 23 '16 at 09:35
  • Mum, how do you get your list of users? From an HTTP call ? ;-) So there is a pitfall here... So perhaps you are in this case. – Thierry Templier May 23 '16 at 09:37
  • 1
    I think you wanted to include a link, but I can't see it! – hY8vVpf3tyR57Xib May 23 '16 at 09:49
  • Yes you're right. In fact, you need to be very carefull with the cast feature in TypeScript. By casting you don't have an instance of an element but this checks that the object has the same structure. But you can't call methods that you could have in a type. See these questions: http://stackoverflow.com/questions/37299649/get-properties-in-angular-2-using-typescript/37299692#37299692 and http://stackoverflow.com/questions/36941990/why-does-casting-from-json-literal-to-type-not-include-functions/36942039#36942039. – Thierry Templier May 23 '16 at 09:53
  • 3
    shouldn't it be `get name()`? – martinoss Jun 07 '17 at 15:38
  • @martinoss yes you're definitely right! I updated my answer accordingly. Thanks very much for pointing this out ;-) – Thierry Templier Jun 08 '17 at 06:07
  • Does this work with Angular 7 ? I am doing exactly the same thing, and the function does not return anything in the template... – fallais Mar 13 '19 at 13:25
1

If the template you are refering to is from your component above you can simple do {{ name() }}. In Angular 2 you dont have to refer to your component first to call methods as it was in Angular 1 the case. In case your class is just a model that you have declared in your componet, you have to get the reference to that model first and then call your method {{ user.name() }}. However, if your method is just a plain getter I would just access a public property instead of calling a method there.

LordTribual
  • 4,219
  • 2
  • 28
  • 38