1

For some reason category is returning undefined.

component

<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" (valueChange)="search()" >
        <mat-option *ngFor="let cate of this.categories" [value]="cate">{{ cate }}</mat-option>
      </mat-select>
    </mat-form-field>
</form>

And the components TypeScript

import { Component } from '@angular/core';
import { Products } from "../../Products";
import { ProductService } from "../../services/product.service";
import {ShoppingCartService} from "../../services/shopping-cart.service";
import {BreakpointObserver, Breakpoints} from "@angular/cdk/layout";
import {FormBuilder, FormControl, FormGroup} from "@angular/forms";

@Component({
  selector: 'app-products',
  templateUrl: './products.component.html',
  styleUrls: ['./products.component.css']
})
export class ProductsComponent {

  searchForm: FormGroup;

  category: string;
  categories: string[] = ['CPU', 'GPU', 'HDD'];
  searchForm: FormGroup;

  constructor() {}

  search(): void {
    console.log(this.category); // undefined

  }

}

I tried binding it many other ways but no more what I do it always returning undefined

3
  • If you want to use 2-way binding then it should be [(value)] and not [value]. And since you are using angular forms, you would need to use [(ngModel)] on the select element Commented Jan 22, 2022 at 16:51
  • I think you should add 'category' as FormControl to your FornGroup. Commented Jan 22, 2022 at 16:58
  • You are mixing template driven and reactive form. Use either one. In your template you have defined as reactive form however in component its template driven form. Commented Jan 22, 2022 at 17:42

1 Answer 1

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>
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.