Angular material two way binding on select returning undefined

Solution 1:

You are missing a few things, let's go step by step. As You are using Reactive Forms, I'll recommend not to use 2-way binding directly i.e. [(ngModel)], rather use the functionality that Reactive Forms provides.

You created the searchFrom: FromGroup, but it's not initialized, so first we have to initialize it, I'll use Angular's FormBuilder Service to achieve that, we'll also need to add the formControl in the searchForm that You are using in Your HTML form group

constructor(private fb: FormBuilder) {} 

ngOnInit(): void {
    this.searchForm = this.fb.group({
        category: [{ value: '', disabled: false }],
    });
}

Now there are two ways you can get the category from mat-select. Either you can utilize the FormControl.valueChanges method or you can use (selectionChange) method of mat-select

The first method will look like this (Recommended):

First we create a method that subscribes to the valueChanges property.

subscribeToCategoryValueChanges(): void {
    this.searchForm.controls.category.valueChanges.subscribe(resp => {
        console.log(resp);
    }); 
}

Then we'll simply call that function in our ngOnInit()

ngOnInit(): void {
     this.searchForm = this.fb.group({
         category: [{ value: '', disabled: false }],
      });

      this.subscribeToCategoryValueChanges();
}

Also, we'll have to remove the search() function from our HTML as it is no longer required

    <form [formGroup]="searchForm" class="login-form d-flex flex-column m-auto">
          <mat-form-field appearance="outline">
              <mat-label>Category</mat-label>
              <mat-select placeholder="Product type" formControlName="category">
                 <mat-option *ngFor="let cate of categories" [value]="cate">{{ 
                 cate }}</mat-option>
               </mat-select>
          </mat-form-field>
    </form>

The second method will look like this:

    search(): void {
       console.log(this.searchForm.controls.category.value);
    }

You'll also have to update your HTML and replace (valueChange) with (selectionChange)

    <form [formGroup]="searchForm" class="login-form d-flex flex-column m-auto">
          <mat-form-field appearance="outline">
              <mat-label>Category</mat-label>
              <mat-select placeholder="Product type" formControlName="category" 
              (selectionChange)="search()" >
                 <mat-option *ngFor="let cate of categories" [value]="cate">{{ 
                 cate }}</mat-option>
               </mat-select>
          </mat-form-field>
    </form>