Search code examples
angularangular-formsangular-formbuilder

Create a dynamic key per user Input using FormGroup Angular 8


I have a form as follows: Form UI

Within the dropdown list are certain pre-defined string values. The Sensor's MAC Address input field has a Pattern check regex.

Goal

I wish to create an object as follows:

{
  'MAC_1': 'location2',
  'MAC_2': 'location3'
}

where the MAC is entered by the user and location comes from dropdown list.

Based on a SE Query it is possible to insert values using patchValue but in the example it only patches the values to an existing key.

How Do I achieve this using Angular Forms?

I have followed the Medium.com Blog on Angular-in-Depth to create reactive forms.

code snippet

export class TestComponent implements OnInit {
    dynamicForm: FormGroup;

    macPattern = '^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})$';

    constructor(private formBuilder: FormBuilder) { }

    ngOnInit() {
        this.dynamicForm = this.formBuilder.group({
            filters: this.formBuilder.array([])
          });
        this.addFilterToFiltersFormArray();
     }


    createFilterGroup() {
        return this.formBuilder.group({
          mac: new FormControl('', Validators.pattern(this.macPattern)),
          loc: []
        });
    }

    get filtersFormArray() {
        return (this.dynamicForm.get('filters') as FormArray);
    }

    addFilterToFiltersFormArray() {
        this.filtersFormArray.push(this.createFilterGroup());
    }

    removeFilterFromFiltersFormArray(index) {
        this.filtersFormArray.removeAt(index);
    }

    getFilterGroupAtIndex(index) {
        return (this.filtersFormArray.at(index) as FormGroup);
    }

    save() {
        console.log(this.dynamicForm.value);
    }
}

which provides me results as follows:

{
  filters: [
     {
       mac: AA:BB:CC:DD:EE:FF,
       loc: location_1
     }
  ]
}

Example Data

[
  filters: 
   {
        {
        mac: 'AA:BB:CC:11:22:DD',
        loc: 'urn:epc:iot:Business.1'
        },
        {
        mac: 'AB:23:24:C3:31:23',
        loc: 'urn:epc:iot:Business.3'
        }
  }
]

Solution

  • You just need to map the results to an Object. But the Reactive Form will give you an array. So just write a mapping function that does that for you.

    Here, give this a try:

    const formData = {
      filters: [{
          mac: 'AA: BB: CC: DD: EE: FF',
          loc: 'location_1'
        },
        {
          mac: 'AB:23:24:C3:31:23',
          loc: 'urn:epc:iot:Business.3'
        }
      ]
    };
    
    const desiredData = {};
    formData.filters.forEach(filter => {
      desiredData[filter.mac] = filter.loc;
    })
    
    console.log(desiredData);