How to populate Map<string, string> using input values

Viewed 162

Stackblitz

I have the following model

export class Items {
  items: Map<string, string>;
  createdBy: string;
  deliveredBy: string;
}

I want to dynamically create input fields based on items in an array which I am able to I am unable to figure out how to populate data in those fields.

<form>
    <tr>
        <td *ngFor="let item of myStringArray">
            Map {{item}}<input name="value" ([ngModel])="data.items.set(item)" (ngModelChange)="onChange()">
    </td>
        <td>
            Always Present One <input ([ngModel])="data.createdBy" (ngModelChange)="onChange()" />
    </td>
        <td>
            Always Present Two<input ([ngModel])="data.deliveredBy" (ngModelChange)="onChange()" />
    </td>
    </tr>
</form>

{{ data.items | json }}

Components.ts

export class AppComponent {
  public myStringArray = ["First", "Second", "Third"];
  data = new Items();

  onChange() {
    console.log(this.data);
  }
}

I found a reference but I am unsure where I am going wrong

Reference Stackblitz

Thank you for your time and help

1 Answers

There are multiple errors in your Stackblitz:

  • You cannot directly bind to a Map within an ngModel. You need to get in the ngModel and set in the ngModelChange:

    <td *ngFor="let item of myStringArray">
      Map {{item}}<input name="value" [ngModel]="data.items.get(item)" 
    (ngModelChange)="data.items.set(item, $event)">
    </td>
    
  • The syntax for the two way binding is "banana in a box" [(...)] not the opposite:

    Always Present One <input [(ngModel)]="data.createdBy" />
    
  • Are per the console error "If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions." you need to either set ngModelOptions or add a name field:

    Always Present One <input [(ngModel)]="data.createdBy" name="createdBy" (ngModelChange)="onChange()" />
    

Here is a new Stackblitz fixed.

Related