6

What I am trying to do is to show the full name, when first name and last name are entered.

This works:

<h1 [hidden]="!firstName || !lastName">Hello {{lastName + ', ' + firstName}}!</h1>

This does not work (what is the correct way of invoking a method defined in the class?):

<!--h1 [hidden]="!firstName || !lastName">Hello {{fullName()}}!</h1!-->

This does not work either:

<button ng-click="alertFullName()">show full name</button>

Here are the files: index.html:

<!DOCTYPE html>
<html>

  <head>
    <title>Angular 2 QuickStart</title>

    <!-- 1. Load libraries -->
    <script src="https://rawgithub.com/systemjs/systemjs/0.19.6/dist/system.js"></script>
    <script src="https://code.angularjs.org/tools/typescript.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.0/angular2-polyfills.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.0/Rx.js"></script>
    <script src="https://code.angularjs.org/2.0.0-beta.0/angular2.dev.js"></script>

    <!-- 2. Configure SystemJS -->
    <script>
      System.config({
        transpiler: 'typescript', 
        typescriptOptions: { emitDecoratorMetadata: true }, 
        packages: {'src': {defaultExtension: 'ts'}} 
      });
    </script>

    <!-- 3. Bootstrap -->
    <script>
      System.import('angular2/platform/browser').then(function(ng){
        System.import('src/hello_world').then(function(src) {
          ng.bootstrap(src.HelloWorld);
        });
      });
    </script>

  </head>

  <!-- 4. Display the application -->
  <body>
    <hello-world>Loading...</hello-world>
  </body>

</html>

src/hello_world.html:

<label>Name:</label>
<input type="text" [(ngModel)]="firstName" placeholder="Enter first name here">
<input type="text" [(ngModel)]="lastName" placeholder="Enter last name here">
<hr>
<h1 [hidden]="!firstName || !lastName">Hello {{lastName + ', ' + firstName}}!</h1>
<!--h1 [hidden]="!firstName || !lastName">Hello {{fullName()}}!</h1!-->
<button ng-click="alertFullName()">show full name</button>

src/hello_world.ts:

import {Component} from 'angular2/core';

@Component({
  // Declare the tag name in index.html to where the component attaches
  selector: 'hello-world',

  // Location of the template for this component
  templateUrl: 'src/hello_world.html'
})
export class HelloWorld {
  firstName: string = '';
  lastName: string = '';
  function fullName(): string {
    return firstName + ', ' + lastName;
  }
  function alertFullName() {
    alert(firstName + ', ' + lastName);
  }
}
TylerH
  • 20,799
  • 66
  • 75
  • 101
Peter Pei Guo
  • 7,770
  • 18
  • 35
  • 54

3 Answers3

3

In addition to what @Günter Zöchbauer wrote (i.e., use (click), not ng-click), this code

function fullName(): string {
   return firstName + ', ' + lastName;
}
function alertFullName() {
  alert(firstName + ', ' + lastName);
}

should be

fullName():string {
    return this.firstName + ', ' + this.lastName;
}
alertFullName() {
   alert(this.firstName + ', ' + this.lastName);
}
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492
2

If we take a look at the documentation for Angular 2 templates we can see that interpolation in the form of {{bindMe}} can bind only to properties:

Expressions can be used to bind to properties only. Expressions represent how data should be projected to the View. Expressions should not have any side effect and should be idempotent.

This means the following example is 'illegal' as it represents a function invocation:

<h1 [hidden]="!firstName || !lastName">Hello {{fullName()}}!</h1>

You could instead have a getter fullName which produces the value you want:

export class HelloWorld {
  firstName: string = '';
  lastName: string = '';
  get fullName () {
      return firstName + ' ' + lastName;
  }
}

And then consume fullName in your template:

<h1 [hidden]="!fullName.length">Hello {{fullName}}!</h1>
Nate Anderson
  • 18,334
  • 18
  • 100
  • 135
sdgluck
  • 24,894
  • 8
  • 75
  • 90
  • 2
    From the [Template Syntax guide](https://angular.io/docs/ts/latest/guide/template-syntax.html#!#interpolation), Interpolation section: "The expression can invoke methods of the host component as we do here with `getVal()`". So I don't think it is illegal to call a method on the component. – Mark Rajcok Dec 23 '15 at 22:14
1

This

<button ng-click="alertFullName()">show full name</button>

should be

<button (click)="alertFullName()">show full name</button>

This works fine for me

<h1 [hidden]="!firstName || !lastName">Hello {{fullName()}}!</h1>

(I had to change the "!firstName || !lastName" expression because I use Dart and there the null check has to be explicit)

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567