'TypeError: ctx.product is undefined

Help ! I'm getting the following error from my Angular (material) application: TypeError: ctx.product is undefined

my service:product.service.ts

@Injectable({
  providedIn: 'root'
})
export class ProductService {

  baseUrl = 'http://localhost:3000/products';


  constructor(
    private http: HttpClient,
    private router: Router,
    private snackBar: MatSnackBar) { }

  // Headers
  private httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json'
    })
  };

  showMessage(msg: string): void {
    this.snackBar.open(msg, 'x', {
      duration: 3000,
      horizontalPosition: "right",
      verticalPosition: "top",
    })
  }

  create(product: Product): Observable<Product> {
    return this.http.post<Product>(this.baseUrl, product);
  }

  read(): Observable<Product[]> {
    return this.http.get<Product[]>(this.baseUrl);

  }

  readByID(id: string): Observable<Product> {
    const url = `${this.baseUrl}/${id}`
    return this.http.get<Product>(url);

  };

  update(product: Product): Observable<Product> {
    const url = `${this.baseUrl}/${product.id}`
    return this.http.put<Product>(url, product);

  };

  // Manipulação de erros
  handleError(error: HttpErrorResponse) {
    let errorMessage = '';
    if (error.error instanceof ErrorEvent) {
      // Erro ocorreu no lado do client
      errorMessage = error.error.message;
    } else {
      // Erro ocorreu no lado do servidor
      errorMessage = `Código do erro: ${error.status}, ` + `menssagem: ${error.message}`;
    }
    console.log(errorMessage);
    return throwError(errorMessage);
  };
}

my component: product-update.component.ts

 @Component({
  selector: 'app-product-update',
  templateUrl: './product-update.component.html',
  styleUrls: ['./product-update.component.css']
})
export class ProductUpdateComponent implements OnInit {

  //product: Product = {} as Product;
  product: Product;

  constructor(
    private productService: ProductService,
    private router: Router,
    private route: ActivatedRoute) { }

  ngOnInit(): void {
    const id = this.route.snapshot.paramMap.get('id');
    console.log(id);
    this.productService.readByID('id').subscribe(product => {
      this.product = product;
    });
  };
  updateProduct(): void {
    this.productService.update(this.product).subscribe(() => {
      this.productService.showMessage('Producto alterado com sucesso !');
      this.router.navigate(['/products']);
    })
  }

  cancel(): void {
    this.router.navigate(['/products']);
  }

}

my form HTML (Angular material):product-update.component.html

<mat-card>
    
    <mat-card-title>Alterar Produto</mat-card-title>
    
    <form>
        
        <mat-form-field>
            <input matInput placeholder="Descrição do produto" [(ngModel)]="product.descricao" name="descricao">
        </mat-form-field>
        <mat-form-field>
            <input matInput placeholder="Grupo do produto" [(ngModel)]="product.id_grupo" name="id_grupo">
        </mat-form-field>
        <mat-form-field>
            <input matInput placeholder="Marca do produto" [(ngModel)]="product.id_marca" name="id_marca">
        </mat-form-field>
        <mat-form-field>
            <input matInput placeholder="Locação do produto" [(ngModel)]="product.id_locacao" name="id_locacao">
        </mat-form-field>
        <mat-form-field>
            <input matInput placeholder="Status do produto A - Ativo ou I - Inativo" [(ngModel)]="product.status" name="status">
        </mat-form-field>
        <mat-form-field>
            <input matInput placeholder="Estoque Mínimo" [(ngModel)]="product.estoque_min" name="estoque_min">
        </mat-form-field>
        <mat-form-field>
            <input matInput placeholder="Estoque Máximo" [(ngModel)]="product.estoque_max" name="estoque_max">
        </mat-form-field>
        
    </form>
    
    <button mat-raised-button (click)="updateProduct()" color="primary">
        Salvar
    </button>
    <button mat-raised-button (click)="cancel()">
        Cancelar
    </button>
</mat-card>

When selecting the item in the list, the following edit form is empty, not bringing the item: enter image description here

The edit form: enter image description here



Solution 1:[1]

postpone form rendering untill you have a product like this

<form *ngIf="product">
...

Solution 2:[2]

Your product: Product in "product-update.component.ts" is not initialized, hence it's undefined. So, assuming your Product is an interface, initialize it using product: Product = new class implements Product { field1: data_type; field2: data_type; };

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Andrei
Solution 2 Harsh patel