error: Uncaught (in promise): Error: Value must be an array in multiple-selection mode

1

Doing a compareWith, for the purpose of when I edit, the dropdowns may already be filled with the assigned values. By doing this, I get this error:

  

Uncaught (in promise): Error: Value must be an array in   multiple-selection mode.

I honestly do not know where he asks for this array as the error says. Here's my html

<div class="container">
    <div class="row">
        <div class="col-md-12">
        <table class="table table-striped table-bordered">
            <caption>
                Lista de Aplicabilidades
                <div class="float-right">
                    <input type="button" class="btn btn-success" (click)="onCreate()" value="+">
                </div>
            </caption>
            <thead class="thead-dark">
                <tr>
                    <th>Nome</th>
                    <th>Contexto</th>
                    <th>Tipo de Pagamento</th>
                    <th>Tipo de Entrega</th>
                    <th>MarketPlace</th>
                    <th></th>
                    <th></th>
                </tr>
            </thead>
            <tbody>
                <tr *ngFor="let aplicabilidade of dataSource" [formGroup]="createForm">
                    <td>
                        <input formControlName="id" type="hidden">
                        <label *ngIf="aplicabilidade.edit != true">{{ aplicabilidade.name }}</label>
                        <label *ngIf="aplicabilidade.edit === true"><input formControlName="name" type="text"></label>
                    </td>
                    <td> 
                        <label *ngIf="aplicabilidade.edit != true">{{ aplicabilidade.context }}</label>
                        <label *ngIf="aplicabilidade.edit === true"><input formControlName="context" type="text"></label>
                    </td>

                    <td>
                        <input formControlName="id" type="hidden">
                        <label *ngIf="aplicabilidade.edit != true">{{ aplicabilidade.typePaymentDetailsModels }}</label>
                        <label *ngIf="aplicabilidade.edit === true">
                                <mat-form-field>
                                    <mat-select multiple [compareWith]="compareValues" 
                                        formControlName="typePaymentDetailsModel" 
                                        placeholder="Tipo de Pagamento" name="payment" >
                                        <mat-option  *ngFor="let payment of dataSourcePayment" [value]="payment.id">   
                                        {{payment.name}}            
                                        </mat-option>
                                    </mat-select>
                                </mat-form-field>
                        </label>
                    </td>
                    <td> 
                        <label *ngIf="aplicabilidade.edit != true">{{ aplicabilidade.typeDeliveryDetailsModels }}</label>
                        <label *ngIf="aplicabilidade.edit === true">
                            <!-- <input formControlName="typeDeliveryDetailsModels" type="text"> -->

                        </label>
                    </td>

                    <td> 
                        <label *ngIf="aplicabilidade.edit != true">{{ aplicabilidade.marketPlace }}</label>
                        <label *ngIf="aplicabilidade.edit === true"><input formControlName="marketPlace" type="text"></label>
                    </td>

                    <td>
                        <fa *ngIf="checkEdit()" name="pencil" (click)="initEditAplicabilidade(aplicabilidade)"></fa>
                        <fa *ngIf="aplicabilidade.edit === true" name="save" (click)="onUpdate()"></fa>
                    </td>
                    <td>
                        <fa *ngIf="checkEdit()" name="times" (click)="onDelete(aplicabilidade)"></fa>
                        <fa *ngIf="aplicabilidade.edit === true" name="ban" (click)="aplicabilidade.edit = null; initDefaultForm();"></fa>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

This is my Component . I put all of it, but it's the compareValues method

export class ApplicabilityComponent implements OnInit {

  createForm: FormGroup;
  public dataSource: Model.ApplicabilityItem[];
  public dataSourcePayment: Model.TypePaymentItem[];
  public dataSourceDelivery: Model.TypeDeliveryItem[];
  public form:any;

  constructor(private _applicabilityService: ApplicabilityService, 
              private builder: FormBuilder, 
              private route: Router) {}

  ngOnInit() {
    this.onGet();
    this.initDefaultForm();    
  }

  initDefaultForm() {
    this.createForm = this.builder.group({
      id: '',
      name: '',
      context: '',
      typeDeliveryDetailsModels: [],
      typePaymentDetailsModel: [],
      marketPlace: false
    });
  }

  onCreate(){
    this.route.navigate(['create-aplicability']);
  }

  onDelete(aplicabilidade: Model.ApplicabilityItem) {
    if (confirm('Deseja excluir o operador: ' + aplicabilidade.name + '?')) {

      this._applicabilityService
        .delete<any>(aplicabilidade.id)
        .subscribe((res) => {
          this.onGet();
        });
    }
  }

  onGet(){
    this._applicabilityService
      .getAllAplicability<Model.Result<Model.ApplicabilityItem>>()
      .subscribe((data: Model.Result<Model.ApplicabilityItem>) =>{
        this.dataSource = data.itens;
      });

      this._applicabilityService
      .getAllDelivery<Model.Result<Model.TypeDeliveryItem>>()
      .subscribe((data: Model.Result<Model.TypeDeliveryItem>) => {
      this.dataSourceDelivery = data.itens;
    }); 

    this._applicabilityService
    .getAllPayment<Model.Result<Model.TypePaymentItem>>()
    .subscribe((data: Model.Result<Model.TypePaymentItem>) => {
      this.dataSourcePayment = data.itens;
    });

  }

  initEditAplicabilidade(aplicabilidade: any){
    aplicabilidade.edit = true;
    this.createForm = this.builder.group({
      id: aplicabilidade.id,
      name: aplicabilidade.name,
      context: aplicabilidade.context,
      typeDeliveryDetailsModels: aplicabilidade.typeDeliveryDetailsModels,
      typePaymentDetailsModel: aplicabilidade.typePaymentDetailsModels,
      marketPlace: aplicabilidade.marketPlace
    });
  }

  checkEdit() {
    if (this.dataSource == null || this.dataSource.length == 0) return false;
      return this.dataSource.filter((item: any) => item.edit === true).length == 0;
  }

  onUpdate(){
    let formValue = this.createForm.value;
    this._applicabilityService.update<Model.Result<Model.ApplicabilityItem>>(formValue)
    .subscribe(success =>{
        this.onGet();
      },
        error =>{
      } 
    );
  }

  compareValues(c1: Model.TypePaymentItem, c2: Model.TypePaymentItem): boolean{
    debugger;
    return c1 && c2 ? c1.id === c2.id : c1 === c2;
  }
}

And my model

export interface ApplicabilityItem{
        id: string,
        name: string,
        context: string,
        typePaymentDetailsModels: TypePaymentItem,
        typeDeliveryDetailsModels: TypeDeliveryItem,
        marketPlace: boolean
    }

    export interface TypePaymentItem{
        id: string,
        sgpTypePaymentId: number,
        name: string
    }

    export interface TypeDeliveryItem{
        id: string,
        sgpTypeDeliveryId: number,
        name: string
    }

What am I missing?

    
asked by anonymous 01.08.2018 / 21:27

2 answers

2

As the documentation itself says:

  

Error: Value must be an array in multiple-selection mode

     

This error is thrown if you attempt to assign it to value other than null , undefined , or an array to a <mat-select multiple> . For example, something like mySelect.value = 'option1' . What you likely meant to do was mySelect.value = ['option1'] .

Translating to Google Translate:

  

Error: value must be an array in multi-select mode

     

This error is thrown if you try to assign a value other than null , undefined , or an array to <mat-select multiple> . For example, something like mySelect.value = 'option1' . What you probably wanted to do was mySelect.value = ['option1'] .

Check the returned values of your services ( console.log ), in some of them, return is probably not one of the valid options

Edit:

The solution is to set the value at creation of FormGroup

initEditAplicabilidade(aplicabilidade: any){
    aplicabilidade.edit = true;
    this.createForm = this.builder.group({
      id: aplicabilidade.id,
      name: aplicabilidade.name,
      context: aplicabilidade.context,
      typeDeliveryDetailsModels: [aplicabilidade.typeDeliveryDetailsModels],
      typePaymentDetailsModel: [aplicabilidade.typePaymentDetailsModels],
      marketPlace: aplicabilidade.marketPlace
    });
}

In FormGroup.group you must pass an object with key being the name and value being an array containing the value and the validations, for example:

{
    nomeDoInput: ['Primeiro passe o valor do campo', [Validators.required,  Validators.pattern(/minha regexp/)]]
}

If you only use a validation, for example, only Validators.required , you can pass without being inside an array:

{
    nomeDoInput: ['Primeiro passe o valor do campo', Validators.required]
}
    
02.08.2018 / 03:43
0

I solved and did not understand until now because it did not work as it is. With the help of a colleague, I did this on my Form on the Angular side (Component). It was a gambi-faced solution, but that was what solved it. I will test for Guilherme Costamilan's answer. I made a get in the "array" of payment and delivery and then assigned the new value, as below.

initEditAplicabilidade(aplicabilidade: any){
    aplicabilidade.edit = true;
    this.createForm = this.builder.group({
      id: aplicabilidade.id,
      name: aplicabilidade.name,
      context: aplicabilidade.context,
      typeDeliveryDetailsModels: [],
      typePaymentDetailsModel: [],
      marketPlace: aplicabilidade.marketPlace
    });

    this.createForm.get('typePaymentDetailsModel').setValue(aplicabilidade.typePaymentDetailsModels);
    this.createForm.get('typeDeliveryDetailsModels').setValue(aplicabilidade.typeDeliveryDetailsModels);
  }
    
02.08.2018 / 14:57