error: Uncaught (in Promise): Error: Value must be an array in Multiple-Selection mode

Asked

Viewed 860 times

1

Giving a compareWith, for the purpose of when I edit, the dropdowns can already be filled with the assigned values. By doing this, I catch this mistake:

Uncaught (in Promise): Error: Value must be an array in Multiple-Selection mode.

I honestly don’t know where he gets this array as the error says. Here is 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 posted all of it, but it’s the way to compare

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?

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 a 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 translator:

Error: value must be a matrix in multiple selection mode

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

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

Edit:

The solution is to define the value in creating the 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 the FormGroup.group you must pass a key object being the name and the 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 one validation, for example, only Validators.required, can pass without being inside an array:

{
    nomeDoInput: ['Primeiro passe o valor do campo', Validators.required]
}

0

I decided and did not understand until now why it did not work as it is. With the help of a colleague, I did it in my Form on the Angular (Component) side. It was a solution, with face of Ambi, but it was what solved. I will test for the answer of Guilherme Costamilan. I got 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);
  }
  • Try to put it that way: ... this.builder.group({ ... typeDeliveryDetailsModels: [aplicabilidade.typePaymentDetailsModels], typePaymentDetailsModel: [aplicabilidade.typeDeliveryDetailsModels], ... works?

  • @Guilhermecostamilam, expensive this way worked and it was very simple and we didn’t see the answer. We tried several ways and believe, less that way. I find this approach cleaner and faceless of Gambi. Thanks!!! If post or edit your answer, I prefer to mark yours than mine, which is more Gambi.

  • As you prefer, I edited my reply with a brief explanation

Browser other questions tagged

You are not signed in. Login or sign up in order to post.