0
votes

I have an angular template form with about 100 inputs. many of them are capturing values from different mat-selection-lists. I was able to bind to ngModel for basic inputs. however, the values from a multi select list is in a string array format. like ["D", "V"]. the API in the backend takes a string for storing the value and I ended up with a lot of manual conversion using JSON.stringify to store it and then using str.split(",") to convert it before binding to the element.

Is there a way in Angular to auto transform the data in ngModel? Is there a way to do this with ControlValueAccessor / Directive ?

<mat-selection-list   [(ngModel)]="formData.input98">
<mat-list-option value="D">D</mat-list-option>
<mat-list-option value="V">V</mat-list-option>
<mat-list-option value="T">T</mat-list-option>
</mat-selection-list>

enter image description here

2

2 Answers

0
votes

Steve, a mat-selection-list with a ngModel yet return an array of values

<mat-selection-list #shoes [(ngModel)]="value">
  <mat-list-option *ngFor="let shoe of typesOfShoes" [value]="shoe">
    {{shoe}}
  </mat-list-option>
</mat-selection-list>

See the stackblitz

Updated, so, in general you has a service

list(){
   return this.httpClient.get(...).pipe(
      map((res:any[])=>{
         res.forEach(x=>{
           x.property=x.property.split(",")
         })
         return res;
      })
   )

get(id){
   return this.httpClient.get(...).pipe(
      map((res:any)=>({...res,property=res.property.split(",")}))
   )
}
save(data:any){
   const dataCopy={...data,property=data.property.join(",")}
   return this.httpCient.post(....dataCopy)
}
0
votes

You map your backend model to a view model before binding and then map it back on save.

this.formData = Object.keys(formData).reduce((mappedData, key) => {
  mappedData[key] = formData[key].split(',');
  return mappedData;
}, {});

and on save go the other way

saveData = Object.keys(this.formData).reduce((mappedData, key) => {
  mappedData[key] = this.formData[key].join(',');
  return mappedData;
}, {});