Search code examples
angularangular-reactive-formsangular-ngselect

how to add an additional property in the object that is assigned to a formControlName


I am getting a response as an array of objects like

taskList = [
{ 'clientTaskId' : '1', 'taskName': 'hardware setup', billableRate: '500'},
{ 'clientTaskId' : '2', 'taskName': 'software installation', billableRate: '250'},
{ 'clientTaskId' : '3', 'taskName': 'environment setup', billableRate: '700'},
{ 'clientTaskId' : '4', 'taskName': 'cafeteria setup', billableRate: '1200'},
];

I am populating this response to an ng-select (multiselect) and then when I select the options, I get the same response format. But I need an additional property 'custom rate' added in the selected object. like

taskList = [
    { 'clientTaskId' : '1', 'taskName': 'hardware setup', billableRate: '500', customRate: ''},
    { 'clientTaskId' : '2', 'taskName': 'software installation', billableRate: '250', customRate: ''},
    { 'clientTaskId' : '3', 'taskName': 'environment setup', billableRate: '700', customRate: ''},
    { 'clientTaskId' : '4', 'taskName': 'cafeteria setup', billableRate: '1200', customRate: ''},
    ];

How can I achieve this, is it possible to achieve this through the concept of assigning a predefined interface to the variable? or by looping and mapping the selected values and appending the customRate property to it.

here is my code :

import {Component, NgModule, ViewChild} from '@angular/core';
import {BrowserModule} from '@angular/platform-browser';
import {FormControl, FormGroup, ReactiveFormsModule, FormsModule, FormBuilder,Validators} from '@angular/forms';
import {NgSelectModule, NgOption} from '@ng-select/ng-select';

@Component({
    selector: 'my-app',
    template: `
        <form (submit)="onClientSave()" [formGroup]="clientForm">
          <ng-select 
                      placeholder="Select custom rates"
                      [items]="taskList"
                      [multiple]="true"
                      bindLabel="taskName"
                      [addTag]="true"
                      [closeOnSelect]="false"
                      clearAllText="Clear"
                      formControlName = "custom"
                      >
                    </ng-select>
        </form>
        <br>
        <pre> {{clientForm.value | json}}</pre>
    `
})
export class AppComponent {

  taskList = [
    { 'clientTaskId' : '1', 'taskName': 'hardware setup', billableRate: '500'},
    { 'clientTaskId' : '2', 'taskName': 'software installation', billableRate: '250'},
    { 'clientTaskId' : '3', 'taskName': 'environment setup', billableRate: '700'},
    { 'clientTaskId' : '4', 'taskName': 'cafeteria setup', billableRate: '1200'},
  ];

   clientForm = this.fb.group({
      custom : [''],
    });

  constructor(
    private fb : FormBuilder
  ){}


}

Here is the stackblitz demo : demo


Solution

  • Something like the following might work. Subscribe to the (add) and (remove) events. I've never used ng-select before so I'm not exactly sure what data gets sent to the event. Here's the code though.

    @Component({
        selector: 'my-app',
        template: `
            <form (submit)="onClientSave()" [formGroup]="clientForm">
              <ng-select 
                          placeholder="Select custom rates"
                          [items]="taskList"
                          [multiple]="true"
                          bindLabel="taskName"
                          [addTag]="true"
                          [closeOnSelect]="false"
                          clearAllText="Clear"
                          (add)="addCustomRate($event)"
                          (remove)="removeCustomRate($event)"
                          formControlName = "custom">
                </ng-select>
            </form>
            <br>
            <pre> {{clientForm.value | json}}</pre>
        `
    })
    export class AppComponent {
    
      taskList = [
        { 
          clientTaskId: 1, 
          taskName: 'hardware setup', 
          billableRate: 500 
        },
        { 
          clientTaskId: 2, 
          taskName: 'software installation', 
          billableRate: 250 
        },
      ];
      clientForm = this.fb.group({
        custom : [''],
      });
    
    
      constructor(
        private fb : FormBuilder
      ){}
    
    
      addCustomRate(item: any): void {
        item.customRate = "";
      }
    
      removeCustomRate(item: any): void {
        delete item.customRate;
      }
    
    }