简体   繁体   中英

Angular2 ngModel binding in the third property level gets undefined

A weird thing is happening on my form or maybe i am not doing it right, let me explain to you by presenting my code.

i have defined a form object inside my component

form = {};

There is a button on each row with data that when you click it opens a modal widow and also passes the item as argument.

<a class="btn btn-warning" (click)="open(item)"><i class="glyphicon glyphicon-pencil"></i></a>

This is the method that fires and opens a modal window but also assign the item object to form object above:

open = (item: any) => {
    this.inventoryEditModal.open(); //Opens a modal window

    this.form = item; // the assignment 
}

The item object is available on the view by printing it out like this:

{{ form | json }} // i can see all item properties

The modal window contains a form where user will edit the item, so basically the input form fields should get filled with item properties values but for some reason the third level is undefined and i don't understand why, let me show you an screenshot of the second level

<input type="text" class="form-control" [(ngModel)]="form.alarmSystem" name="wireless">

在此处输入图片说明

The third level gets undefined:

<input type="text" class="form-control" [(ngModel)]="form.alarmSystem.wireless" name="wireless">

在此处输入图片说明

This issue is happening only for the third level "object.object.property". I am only showing one input field but the form contains more than 8 fields they all have same issue.

Not sure what i am missing here, but logically it should work. Do you have see this issue happening here and there or experienced your self?

Thank you in advance.

I am not sure if it helps your case, but I was in a very similar situation.

What helped me out was using the "safe-navigation-operator".

I assume that what you need to do is just add the ? after form :

<input type="text" class="form-control" [(ngModel)]="form?.alarmSystem.wireless" name="wireless">

The docs can be found here: https://angular.io/docs/ts/latest/guide/template-syntax.html#!#safe-navigation-operator

There can be 3 possible solutions with Angular 5

  1. Don't assign ngForm to the template variable of the form (in form HTML element)

Don't do this -

<form #newItem="ngForm" (ngSubmit)="saveItem(newItem.value);">

Instead, do this -

    <form (ngSubmit)="saveItem();">
        <input type="text" class="form-control" name="wireless [(ngModel)]="form.alarmSystem.wireless">
        <submit type="submit">Save</submit>
    </form>

By this, you will be able to assign a 3 level nested property to [(ngModel)] without any elvis or safe navigation operator (?).


  1. If you are assigning ngForm to the form template variable then [(ngModel)] will give undefined for a 3 level nested property even if it already has some value. So, use the name attribute instead -

     <form #newItem="ngForm" (ngSubmit)="saveItem(newItem.value);"> <input type="text" name="alarmSystem.wireless" ngModel class="form-control"> </form>

Now, in this case, the nested property alarmSystem.wireless assigned to the name attribute will be bound 2-way using ngModel directive. And you can easily access it in the Event emitter function.


  1. And the last solution by using elvis operator (?) is -

Here, again we will not assign ngForm in the form template variable, although there will not be any error but it won't store the value entered in input correctly. So, split 2-way data binding with [ngModel] and (ngModelChange) like this

<form (ngSubmit)="saveItem();">
    <input type="text" name="wireless" 
                            [ngModel]="form?.alarmSystem?.wireless"
                            (ngModelChange)="form.alarmSystem.wireless=$event" class="form-control">
</form>

Also you can refer to this answer - Correct use of Elvis operator in Angular2 for Dart component's view

But, I don't recommend this solution as it adds up a lot of code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM