angular2: Error: TypeError: Cannot read property &

2018-12-31 22:28发布

问题:

I have attached the plunker of my angular2 code piece. I want to print a field from my JSON but unable to print that as initially my Object is null and it is being populated via a Promise.

This is my component file

import {Component, NgModule, OnInit} from \'@angular/core\'
import {BrowserModule} from \'@angular/platform-browser\'

class MyData {
  xyz : MySubData;
}

class MySubData {
  name : string;
} 
@Component({
  selector: \'my-app\',
  template: `
    <div>
      <h2>Hello {{name}}</h2>

      {{abc.xyz.name}}
    </div>
  `,
})
export class App implements OnInit {
  abc : MyData = null;
  constructor() {
    this.name = \'Angular2\'
  }

  ngOnInit() {
    setTimeout(() => {
      this.abc = new MyData();
      this.abc.xyz = new MySubData();
      this.abc.xyz.name = \"Binita\";
    }, 2000);
  }
}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}

When I am removing the line {{abc.xyz.name}} from my template it is running fine.

I have use set time out in my code because I am getting my data from Promise (i.e asynchronous call).

I can understand initially as abc is null, my code is unable to find abc.xyz.name. But I don\'t want to put any if condition to check. Because I have several property inside a JSON and it is not possible for each property to write if condition.

Earlier in angularjs 1 if abc is null then it would automatically replace it with blank string. I want to do the same thing in angular2. Please suggest.

Below is the plunker

https://plnkr.co/edit/u1NqNF0penz7OS55QmoU?p=preview

回答1:

That\'s because abc is undefined at the moment of the template rendering. You can use safe navigation operator (?) to \"protect\" template until HTTP call is completed:

{{abc?.xyz?.name}}

You can read more about safe navigation operator here.

Update:

Safe navigation operator can\'t be used in arrays, you will have to take advantage of NgIf directive to overcome this problem:

<div *ngIf=\"arr && arr.length > 0\">
    {{arr[0].name}}
</div>

Read more about NgIf directive here.



回答2:

Safe navigation operator or Existential Operator or Null Propagation Operator is supported in Angular Template. Suppose you have Component class

  myObj:any = {
    doSomething: function () { console.log(\'doing something\'); return \'doing something\'; },
  };
  myArray:any;
  constructor() { }

  ngOnInit() {
    this.myArray = [this.myObj];
  }

You can use it in template html file as following:

<div>test-1: {{  myObj?.doSomething()}}</div>
<div>test-2: {{  myArray[0].doSomething()}}</div>
<div>test-3: {{  myArray[2]?.doSomething()}}</div>