Working with 2-way databinding on angular 2+.
1) I have a variable in my compoent: user: User, which is a simple json object (model) containing 2 fields: name, pass;
2) this variable fills in onInit method thru http request:
this.userService.getUser.subscribe(res => {
this.user = res;
}
3) on my html I want to display current name and 2-way bind it between user variable (ts) and input field (html). To do So I did:
<mat-form-field>
<input matInput type="text" id="name" [(ngModel)]="user.name" name="name"
placeholder="name">
</mat-form-field>
</form>
^ for now submit() only prints user to console.
All of above works just fine, except it prints an error in console: Cannot read property 'name' of undefined. Looks like while request which getting user from server in progress, angular is trying to display the html and there is undefined user object. Error disappears when I instantly initialize user with empty object like: user:
User = new User();
How to deal with this ? How can I tell angular not to hurry ? Do I correctly understand what is happening ?
I tried to add "?" on
[(ngModel)]="user?.name"
to make it kinda optional, got another error.
The safe navigation / Elvis operator (?
) is not working in this case, you cannot use it with two-way binding without doing some more work.
Either you're instantiating a dummy user object (as you mentioned yourself already) or you prevent rendering the input until the user is loaded via something like that:
<input [(ngModel)]="user.name" *ngIf="user else userIsLoadingInfo" matInput id="name" name="name">
<ng-template #userIsLoadingInfo>Loading...</ng-template>
You can also leave out the ng-template
part that shows a loading information. It highly depends on what is expected from a user experience perspective (loading info vs. empty text box vs. nothing ...)