0

I have two selects, Category and Subcategory, on subcategory select i am filtering data based on category value.

Also if user wants he/she can add new row and add new data.

  // create another field for categories
  createCat(array: any, form: any) {
    let formgroup = this.fb.group({
      carPartCategory: ['', Validators.required],
      carPartSubCategory: ['', Validators.required],
      quantity: ['', Validators.required],
      comment: [''],
    });
    this.formArrCat.push(formgroup);
  }

my issue is that: if there is more then 1 row and i select value in category select, all subcategory selects change value.

  // get car part subcategory
  getCarPartsSubCategory(event: any) {
    let value = event.value;
    this.inputValue = [];
    console.log(value);
    this.inputValue = [...this.inputValue, ...value.carPartSubCategories];
    this.filteredcarPartsSub.next(this.inputValue);
  }

how can i make value stay same in other formgroups when i am chooosing it in different row?

here is my stackblitz

.html

 <mat-form-field appearance="fill" class="nusx">
      <mat-label>Choose Category</mat-label>
      <mat-select #multiSelect formControlName="carPartCategory"
        (selectionChange)="onChange($event); getCarPartsSubCategory($event)">
        <mat-option>
        <ngx-mat-select-search [formControl]="carPartsMultiFilterCtrl" [placeholderLabel]="'search...'"
          [noEntriesFoundLabel]="'not found'">
        </ngx-mat-select-search>
      </mat-option>
        <mat-option *ngFor="let item of filteredcarParts | async" [value]="item">{{item.name}}
        </mat-option>
      </mat-select>
    </mat-form-field>

    <mat-form-field appearance="fill" class="nusx">
      <mat-label>Choose Subcategory</mat-label>
      <mat-select #multiSelect formControlName="carPartSubCategory">
      <mat-option>
      <ngx-mat-select-search [formControl]="carPartsSubMultiFilterCtrl"
        [placeholderLabel]="'search...'" [noEntriesFoundLabel]="'not found'">>
      </ngx-mat-select-search>
    </mat-option>
        <mat-option *ngFor="let item of filteredcarPartsSub | async; let i = index;" [value]="item">
          {{item.name}}
        </mat-option>
      </mat-select>
    </mat-form-field>
4
  • You use the same Subject (filteredcarPartsSub) for each row. So every time you change a category, all subcategories are going to be reseted. Commented Mar 1, 2022 at 13:54
  • Hi! thanks for the comment. how can i use different subject for every row? Commented Mar 1, 2022 at 17:16
  • What if you use an array of subjects? Commented Mar 1, 2022 at 18:00
  • You are using the same data as a source for all subcategories, you need to have different source for each row Commented Mar 7, 2022 at 23:27

1 Answer 1

1
+100

One solution would be to add a control for your options to the formGroup so that you can retrieve it from the formArray via index.

Add carPartSubCategoryOptions to both your createCat and initCat functions.

 initCat() {
    return this.fb.group({
      carPartCategory: ['', Validators.required],
      carPartSubCategory: ['', Validators.required],
      carPartSubCategoryOptions: [''], // add this
      quantity: ['', Validators.required],
      comment: [''],
    });
  }

Create helper function to retrieve that control via formArray index value

  // get options category by index
  getCarPartSubCategoryOptions(i) {
    const formArray = this.filterForm.get('categories') as FormArray;
    const formGroup = formArray.controls[i] as FormGroup;
    const optionsControl = formGroup.get('carPartSubCategoryOptions');
    return optionsControl;
  }

Modify the getCarPartsSubCategory helper function to receive formArray index as the second argument, call the new helper function using that index, and set this.input to the control as value.

// get car part subcategory
  getCarPartsSubCategory(event: any, i) {
    let value = event.value;
    this.inputValue = [];
    console.log(value);
    this.inputValue = [...this.inputValue, ...value.carPartSubCategories];
    const optionsControl = this.getCarPartSubCategoryOptions(i); // call helper using index
    optionsControl.setValue(this.inputValue); // set value to control
  }

Then change markup to *ngFor over the value of that control via the new helper function.

 <mat-option *ngFor="let item of this.getCarPartSubCategoryOptions(i).value" [value]="item">
                      {{ item.name }}
                    </mat-option>

STACKBLITZ

https://stackblitz.com/edit/angular-ivy-fcuk7b?file=src/app/app.component.html

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you so much for detailed answer!! i rly appreciate it! cani ask you one more question? i used ngx-mat-select for searching in select, it works for car parts but how can i make it work with your function? i edited my stackblitz stackblitz.com/edit/angular-ivy-jfnt2k?file=src/app/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.