angular - 无法读取未定义的 CRUD 操作的类型 '_id ' 的属性

标签 angular express mongoose crud

我对 Angular 相当陌生,刚刚实现 CRUD 操作。我正在使用一个 Express 服务器,它使用 mongoose 作为后端,前端是 Angular 。

我的 express 服务器工作正常,我可以执行所有请求,并且可以获得要在我的 Angular 应用程序中显示的产品列表。

当我点击产品或尝试删除产品时,我收到“无法读取类型为‘_id’的属性” 未定义”

我的问题是如何使用 ID 定义我点击或删除的特定产品,因为这是删除请求所需的内容,或者我在哪里出错了?我并不真正理解未定义的错误,因为我可以获取所有产品并显示它们的 ID、名称品牌等..

我在我的产品模型和 isbn 中使用 _id,因为在 postman 中创建的 id 使用 _id,这是我删除所需的 _id。

这是我的产品服务

import { Injectable } from '@angular/core';
import {IProduct} from 'model/product'
import { HttpClient, HttpErrorResponse, HttpHeaders } from '@angular/common/http';
import { Observable, of, throwError } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators'

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

  private dataUri ='http://localhost:5000/Beauty'

  constructor(private http: HttpClient) { }

  getProducts():Observable<IProduct[]>{

    console.log("get products called"); 

    return this.http.get<IProduct[]>(`${this.dataUri}?limit=10`)
      .pipe(
        catchError(this.handleError
          )
      )
  }

  getProductById(id: string): Observable<any>{
    return this.http.get(`${this.dataUri}/${id}`)
  }

  addProduct(product: IProduct): Observable<IProduct>{
    return this.http.post<IProduct>(this.dataUri, product)
    .pipe(
      catchError(this.handleError)
    )
  }

  updateProduct(id:string, product: IProduct): Observable<IProduct>{
    console.log('subscrbing to update' + id); 
    let productURI: string = this.dataUri + '/' + id; 
    return this.http.put<IProduct>(productURI, product)
    .pipe(
      catchError(this.handleError)
    )
  }

  deleteProduct(_id : string) : Observable<IProduct>{
    let productURI: string = this.dataUri + '/' + (_id); 
    return this.http.delete<IProduct>(productURI)
    .pipe(
      catchError(this.handleError)
    )
  
   }

  private handleError(error: HttpErrorResponse) {
    if (error.error instanceof ErrorEvent) {
      // A client-side or network error occurred. Handle it accordingly.
      console.error('An error occurred:', error.error.message);
    } else {
      // The backend returned an unsuccessful response code.
      // The response body may contain clues as to what went wrong.
      console.error(
        `Backend returned code ${error.status}, ` +
        `body was: ${error.error}`);
    }
    // Return an observable with a user-facing error message.
    return throwError(
      'Something bad happened; please try again later.');
  }

}


这是产品增删改查组件

import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import {IProduct} from 'model/product'
import { Observable } from 'rxjs';
import { ProductService } from '../product.service';

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

  products: IProduct[];  
  message:string;

  currentproduct: IProduct; 

  constructor(private productservice: ProductService, 
    private router: Router) { }
  ngOnInit(): void {
    this.loadProducts(); 
  }

  clicked(product: IProduct):void{
    this.currentproduct = product; 
    console.log(this.currentproduct._id); 
  }
  loadProducts(){

    this.productservice.getProducts().subscribe({
      next:(value: IProduct[])=> this.products = value, 
      complete: () => console.log('product service finished'), 
      error:(mess) => this.message = mess
    })

  }
  deleteProduct(_id: string, product: IProduct)
  {
    console.log('deleting product'); 

    this.productservice.deleteProduct(product._id)
    .subscribe({
      next:product => this.message = "product is deleted", 
      complete: () => console.log("deleted product"), 
      error: (mess) => this.message = mess
    })
  }
     updateProduct(_id: string){
      this.router.navigate(['update', _id]);
    }

}

和product-crud组件html

<div class="panel panel primary">
    <div class="panel-heading">
        <h2>Product List</h2>
    </div>

    <div class="panel-body">
        <table class="table table-striped">
            <thead>
                <tr>
                    <th>
                        Name
                    </th>
                    <th>
                        Category
                    </th>
                    <th>
                        Brand
                    </th>
                    <th>
                        Price
                    </th>
                    <th>
                        id
                    </th>
                </tr>
            </thead>
            <tbody>
                <tr *ngFor="let product of products"
                [product] = "p"
                (click) = 'clicked(p)'>
                    <td>{{product.name}}</td>
                    <td>{{product.category}}</td>
                    <td>{{product.brand}}</td>
                    <td>{{product.price}}</td>
                    <td>{{product.isbn}}</td>
                    <td><button (click)="deleteProduct(product.id)" class="btn btn-danger">Delete</button>
                       <button (click)="updateProduct(product.id)" class="btn btn-info" style="margin-left: 10px">Update</button>
                        <button (click)="detailproduct(product.id)" class="btn btn-info" style="margin-left: 10px">Details</button> 
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

最佳答案

查看组件中的功能,进行以下更改应该可以使其正常工作。

  1. <tr *ngFor="let product of products" (click) = "clicked(product)"> 这里的product是一个你需要传递的局部变量。

  2. 此外,函数签名 deleteProduct(product.id)和函数调用(click)="deleteProduct(product.id)"不匹配。

您可能想将它们更改为类似 (click)="deleteProduct(product._id, product)" 的内容。同样检查并修改其他函数调用。

关于angular - 无法读取未定义的 CRUD 操作的类型 '_id ' 的属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66768004/

相关文章:

css - 如何通过单击其子项(angular2/ts)将样式应用于 div 元素

android - Ionic Cordova QrScanner 布局不一致?

angular - 不兼容的 SockJS!主站使用: "1.1.4", iframe : "1.0.0". 怎么处理?

javascript - Node 邮件错误 : self signed certificate in certificate chain

node.js - Node JS Passport google oauth 无法在 https 上工作?

Javascript 和 mongodb,如何将条件数组传递给查询

node.js - 使用node js从mongodb获取数据

mongodb - Mongoose - 填充后更新(Cast Exception)

Angular 9 : Using angular i18n along with server side rendering (angular universal)

javascript - 运行 Nodemon 时出现问题 : "[nodemon] clean exit - waiting for changes before restart"