Angular Property has no initializer and is not definitely assigned in the constructor
In this post you will learn how to fix the most popular Angular problem and it is "Property has no initializer".
When do we get this error? Here I already prepared for us an empty Angular project. The only thing that I created is child.component.ts
.
@Component({
selector: 'child',
template: '<div>Child</div>'
})
export class ChildComponent {}
If we try to add an Input
property to this component we will get an error.
@Component({
selector: 'child',
template: '<div>Child</div>'
})
export class ChildComponent {
@Input() currentPage: number;
}
As you can see in console we are getting an error "Property has no initializer and is not definitely assigned in the constructor"
What does it mean? Here we are talking not about Angular but about Typescript. And Typescript inside this child component doesn't see that we initialized currentPage
property.
Bad solution: any
Now let's look on the wrong solutions to this problem. First fix that people do is write any
.
@Input() currentPage: any;
In this case we don't get any errors from the Typescript and we solved the problem. But we stopped using Typescript at all and it doesn't make any sense to do that.
Bad solution: disabling error
Another possible variant is just to disable this rule in tsconfig.json
.
// tsconfig.json
{
"compilerOptions": {
"strictPropertyInitialization": false
}
}
Here we added strictPropertyInitialization
and set it to false. It disables the error completely.
We can also change the whole project to strict
: false.
This is also wrong because you want your project to be as strict as possible and you want to get all your errors not in runtime but in compiling time.
So so solution: suppress warning
One more solution which is so so is to put an exclamation mark.
@Input() currentPage!: number;
It tells Typescript what we are 100% sure that we will get currentPage
on initialize of our component. We promise Typescript that it will never be undefined.
But realistically it is wrong because any developer can call a component without an input.
Good solution: default value
What solutions do we have here? The first solution is to provide a default value. This is the best possible fix is you can do that.
@Input() currentPage: number = 0;
For example for currentPage
we can say that the default value is zero and we are good to go. Your component will never be broken even if somebody will create it without an input.
And cool thing that you can do with default value with strings if you don't really want to set a default value is this.
@Input() name: string = 'Not implemented'
Your component won't be broken and other developers will see Not implemented
and understand that they didn't provide enough information inside this component.
Good solution: undefined
Another solution that you can use in any case is default to undefined.
@Input() currentPage: number | undefined;
In this case we say that our currentPage
might be undefined and our component must be prepared to work without a value.
This is the most flexible and correct fix which is possible.
But here is the problem. Now in every single place in our component we must check that our currentPage
is really set and it is not undefined. And it is even worse if we are talking about nested objects like for example the whole interface of the user.
So realistically all variants except of default value and setting it as undefined are bad.
Want to conquer your next JavaScript interview? Download my FREE PDF - Pass Your JS Interview with Confidence and start preparing for success today!