1

I have a form with a telephone field, when you click on the Add button, a new field will appear. What is happening is that when I click on Add, the value typed on the previous fields get reset. I managed to make it work by removing the "form" tags, but I need this form on my project. How can I make it work using "form"?

HTML

<form>
   <div *ngFor="let phonecount of phonecount; let i = index" class="form-group">
<label>Optional Phone </label>
<input type="text" class="form-control" [(ngModel)]="user.extraphones[i]" name="phone2">
 </div>
<input (click)="onSubmito()" type="submit" value="Add" class="btn btn-primary">
</form>

TS

user = {
          name:'',
          phone:'',
          extraphones:[]
      };
  namee='';
   phonecount:string[]=[''];
onSubmito(){
  this.phonecount.push(this.namee);
}

Punkler: https://plnkr.co/edit/i85x1m?p=preview

1
  • phonecount and user.extraphones are not related by any means. This is the root of your issue. Commented Oct 16, 2017 at 0:12

1 Answer 1

3

Make sure you're binding to the right thing. Similarly, make sure that a proper collection is being updated when use clicks "Add".

After understanding you problem better I found this SO answer and this GitHub issue.

Was able to fix your issue... Notice the following things:

  • trackBy:trackById in template and trackById function in typescript code.
  • name attribute on <input> field.

//our root app component
import {Component, NgModule, VERSION} from '@angular/core'
import {FormsModule} from '@angular/forms'
import {BrowserModule} from '@angular/platform-browser'

export class Info {
  id: number;
  description: string;
}

    @Component({
      selector: 'my-app',
      template: `
      <form>
       <div *ngFor="let ph of user.extraphones; let i = index; trackBy:trackByIndex" class="form-group">
        <label>Optional Phone</label>
        <input type="text" class="form-control"
          [(ngModel)]="user.extraphones[i]" name="item-{{i}}">
      </div>
      <input (click)="onSubmito()" type="submit" value="Add" class="btn btn-primary">
    </form>

      {{ user.extraphones | json }}
      `,
    })
    export class App {
      user = {
              id:'',
              _id:String,
              name:'',
              phone:'',
              extraphones:['123', '345', '678'],
              rank:''
          };

      namee='';

      onSubmito(){
        this.user.extraphones.push(this.namee);
      }

      trackByIndex(index: number, value: number) {
        return index;
      }
      }
    }

@NgModule({
  imports: [ BrowserModule, FormsModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}
Sign up to request clarification or add additional context in comments.

5 Comments

I will try this. But wouldn't changing the input ngmodel to 'phone' makes it insert into phone property instead of extraphones?
@Gustavo I have modified both the template and the TS code so that it's easier for you to understand, what's going on. I also strongly recommend you using better names.
The array values sent on this form is not as expected. It's getting the 'namee' property value and adding to all array values except the first one (I'm sending this trough a REST API). I changed the namee value on TS to = 'somedata' to explain better. Here's what's happen when I send 3 fields with different values: extraphones:(3) ["", "somedata", "somedata"]
@Gustavo now I see shy. Storing phones as array of strings is a horrible idea for many reasons. One of them is that Angular will not be able to detect the changes (since string is a primitive type) unless we specially instruct it. Notice name attribute on input tag; and trackById function. Read about them to get a better idea about what's going on.
Hope I answered your question this time :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.