You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MEAN Stack问题:无法通过ID显示单个MongoDB元素详情

解决MEAN Stack详情页无法显示对应元素数据的问题

我帮你梳理了整个流程里的几个关键问题,这些就是导致详情页拿不到对应数据的原因,逐个修正就能解决:

1. 后端API查询条件错误(api.js)

MongoDB集合的默认主键字段是_id,但你在getProduct接口里用了id作为查询字段,这直接导致找不到目标文档。另外Promise的catch和then顺序写反了,会让错误处理逻辑混乱。

修正后的getProduct接口代码:

router.post('/getProduct',(req, res) => {
  connection((db) => {
    db.collection('products')
      // 把查询字段从id改为_id,匹配MongoDB主键
      .find({_id: new ObjectID(req.query.id)})
      .toArray()
      .then((result)=>{
        response.data= result;
        response.message ={ success:"Se obtuvieron los registros correctamente", error:""};
        res.send({response});
      })
      // 将catch移到then之后,正确捕获异常
      .catch((err)=>{
        sendError(err, res);
      });
  });
});

2. Angular服务层参数传递错误(mongo2.service.ts)

你现在把id参数放在了POST请求的body里,但后端是通过req.query.id获取参数的,所以得把id作为URL查询参数传递。另外MongoDB的_id是字符串类型,不要转成数字。

修正后的getProduct方法:

import { HttpParams } from '@angular/common/http';

// ...其他代码不变
getProduct(id: string) {
  const headers = new HttpHeaders({'Content-Type': 'application/json' });
  // 用HttpParams构造查询参数
  const params = new HttpParams().set('id', id);
  // params作为第三个参数传递,请求体传空对象即可
  return this._http.post('/api/getProduct', {}, { headers, params })
    .catch( (error: any) => Observable.throw(error || 'server error'));
}

3. 详情组件的路由参数与数据处理错误(details.component.ts)

  • 构造函数里多了一个多余的逗号,会导致编译报错
  • 不要用+把_id转成数字,MongoDB的_id是字符串格式的ObjectID
  • 后端返回的是数组,要取第一个元素作为单个产品数据

修正后的组件代码:

import { Component, OnInit } from '@angular/core';
import {Location} from '@angular/common';
import {ActivatedRoute} from '@angular/router';
import {Mongo2Service} from '../mongo2.service';

@Component({
  selector: 'app-details',
  templateUrl: './details.component.html',
  styleUrls: ['./details.component.css']
})
export class DetailsComponent implements OnInit {
  respuesta: any;
  product: any; // 单个产品用product命名更合理

  constructor(
    private location: Location, 
    private route: ActivatedRoute, 
    private mongo2Service: Mongo2Service // 去掉多余的逗号
  ) { }

  ngOnInit() {
    this.getProduct();
  }

  getProduct() {
    // 直接获取字符串类型的_id,无需转数字
    const id = this.route.snapshot.paramMap.get('_id');
    console.log('进入详情组件,当前ID:', id);
    this.mongo2Service.getProduct(id).subscribe(respuesta => {
      this.respuesta = respuesta;
      // 从返回的数组中取出第一个元素
      this.product = this.respuesta.response.data[0];
      console.log('获取到的产品数据:', this.product);
    });
  }

  goBack(): void{
    this.location.back();
  }
}

4. 详情页模板的适配建议(details.component.html)

因为接口返回的是数组,模板里要针对单个产品数据渲染:

<div *ngIf="product">
  <h2>{{product.name}}</h2>
  <p>产品ID: {{product._id}}</p>
  <!-- 其他需要展示的字段 -->
</div>

额外优化小提示

  • 单个资源的获取建议用GET请求而非POST,更符合RESTful规范,比如后端改成router.get('/product/:id'),服务层用this._http.get('/api/product/' + id)
  • 可以在服务层直接处理返回的嵌套数据,比如返回respuesta.response.data[0],让组件代码更简洁

内容的提问来源于stack exchange,提问作者Aramis Delgado

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 07:22:38