1

I have component, where I show data, got from back end.

Here is function for showing data

 getData() {
    this.propertyService.getPropertyForEdit(Number(this.activatedRoute.snapshot.params['id'])).subscribe(r => {
        this.property = r;
        this.tabTemplates = [
            { title: this.l('Addresses'), template: this.addressesTemplateRef },
            { title: this.l('Site'), template: this.siteTemplateRef}
        ];
        this.propertiesToDisplay = [
            { displayName: this.l('PropertyTitle'), value: this.property.propertyTitle.name},
            { displayName: this.l('Landlord'), value: this.property.landlord.name},
            { displayName: this.l('Agent'), value: this.property.agent.name },
            { displayName: this.l('BuildingType'), value: this.property.buildingType.name }
        ];
    });
}

In this row value: this.property.landlord.name} value can be null.

So when it null, I have error

Cannot read property 'name' of undefined

How I can fix this?

Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
Eugene Sukh
  • 2,357
  • 4
  • 42
  • 86
  • `this.property.landlord.name || "N/A"` try doing this – Kunal Mukherjee Apr 17 '19 at 07:23
  • `this.property.landlord` is undefined. You should check for landlord existing using **fallbacks**. `(this.property && this.property.landlord && this.property.landlord.name) ? this.property.landlord.name : 'N/A'` – briosheje Apr 17 '19 at 07:25
  • Or use .map and do the same for all undefined values. – Zydnar Apr 17 '19 at 07:26
  • Possible duplicate of [Test for existence of nested JavaScript object key](https://stackoverflow.com/questions/2631001/test-for-existence-of-nested-javascript-object-key) – Kunal Mukherjee Apr 17 '19 at 07:31

4 Answers4

3

Use a ternary operator:

value: (this.property.landlord ? this.property.landlord.name : "defaultValue")
Jack Bashford
  • 43,180
  • 11
  • 50
  • 79
3

So when it null, I have error

Cannot read property 'name' of undefined

No, it's not null, it's undefined, which is different.

The error is thrown because this.property.landlord is undefined. In javascript, trying to access a property (in this case name) of undefined throws a TypeError, by design.

To solve the issue (which is not an issue, but rather a case), you should use fallbacks to check whether ancestors of the property exists. In this case, I would handle that in this way:

{ displayName: this.l('Landlord'), value: (this.property && this.property.landlord && this.property.landlord.name) ? this.property.landlord.name : 'N/A'},

That piece of code specifically:

this.property && this.property.landlord && this.property.landlord.name

will assert that every ancestor of name exists. If any of these doesn't, it will return 'N/A' without throwing any exception.

briosheje
  • 7,356
  • 2
  • 32
  • 54
  • @EugeneSukh from your post, I may guess that you're using `angular`. If so, if the variable is directly printed in the html template, you can use the **elvis operator** to avoid the above checks, but it will work **only in angular templates**: `property?.landlord?.name`. If so, you may take a look at this: https://stackoverflow.com/questions/35161789/correct-use-of-elvis-operator-in-angular2-for-dart-components-view/35162228 – briosheje Apr 17 '19 at 07:36
2

The problem is the property landlord is null(undefined). You can directly handle the null check using ternary operators.

value: (this.property.landlord) ? this.property.landlord.name : null

1

Use ternary condition while assigning value. Like this

{ displayName: this.l('PropertyTitle'), value: (this.property.propertyTitle.name) ? this.property.propertyTitle.name: null},
Zarna Borda
  • 695
  • 1
  • 6
  • 22