0%

angular-troubleshooting-setter-getter

Introduction

The get syntax binds an object property to a function that will be called when that property is looked up. It can also be used in classes.

Here is an example:

1

Case

When you use getter, you would better provide setter for the property too. If you only provide getter, you might got errors, here is a real case.

We have a child component with a name property, and we want to format the name to uppercase in the child component. the name property is passed from the parent component.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// child.component.ts
@Component({
standalone: true,
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent {
private _name = '';

@Input() set name(name: string) {
this._name = name
}

formatName(name: string) {
return name.toUpperCase();
}
}
1
2
<!-- child.component.html -->
<div>Uppercase name: {{ formatName(name) }}</div>

And in the parent component’s template, we pass the name property to the child component.

1
2
<!-- parent.component.html -->
<app-child name="Philip"></app-child>

When you run the code, you will get the following error:

1
TypeError: Cannot read properties of undefined (reading 'toUpperCase')

The error is caused by the formatName function in the child component, here name is undefined, we can’t call toUpperCase on undefined, but why?

1
return name.toUpperCase();

When we read name in the formatName function, it will trigger the getter of the name property, but we only provide the setter for the name property, so name is undefined.

To fix this error, we need to provide the getter for the name property.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// child.component.ts
@Component({
standalone: true,
selector: 'app-child',
templateUrl: './child.component.html',
styleUrls: ['./child.component.css']
})
export class ChildComponent {
private _name = '';

@Input() set name(name: string) {
this._name = name
}

get name() {
return this._name;
}

formatName(name: string) {
return name.toUpperCase();
}
}

References:

  1. get in object