【问题标题】:MEAN stack: can't display data from a single Mongodb element by it's idMEAN堆栈:无法通过其ID显示来自单个Mongodb元素的数据
【发布时间】:2018-05-22 13:50:57
【问题描述】:

使用服务和 api 连接到我能够在 catalog.component.ts 中显示我的 mongodb 集合中的整个数组: api.js

const express = require('express');
const router=express.Router();

const app=express();
const MongoClient=require('mongodb').MongoClient;
const ObjectID=require('mongodb').ObjectID;
var path=require('path');
var db;

const connection=(closure) => {
    return MongoClient.connect('mongodb://localhost:27017', (err, client)=>{
        if (err) return console.log(err);
        db=client.db('angulardb');
        closure(db);

    });
};


const sendError =(err, res)=>{
    response.status=501;
    response.message=typeof err == 'object' ? err.message : err;
    res.status(501).json(response);
};

let response={
    status:200,
    data:[],
    message: null
};

router.post('/getProducts',(req, res) => {

  connection((db) => {
    db.collection('products')
      .find()
      .toArray()
      .catch((err)=>{
        sendError(err, res);
        response.message ={ success:"Se obtuvieron los registros correctamente", error:""};
        res.send({response});
      })
      .then((result)=>{

        response.data= result;
        res.send({response});
      });
  });
});

router.post('/getProduct',(req, res) => {
  connection((db) => {
    db.collection('products')
      .find({id:new ObjectID(req.query.id)})
      .toArray()
      .catch((err)=>{
        sendError(err, res);
        response.message ={ success:"Se obtuvieron los registros correctamente", error:""};
        res.send({response});
      })
      .then((result)=>{

        response.data= result;
        res.send({response});
      });
  });
});
module.exports=router;

我为目录添加了 getProducts 函数并为详细信息添加了 getProduct 函数的服务

mongo2.service.ts:

import { Injectable } from '@angular/core';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/toPromise';
import {HttpClient, HttpHeaders} from '@angular/common/http';
@Injectable()
export class Mongo2Service {

  constructor( private _http: HttpClient) { }


  getProducts() {
    const headers = new HttpHeaders({'Content-Type': 'application/json' });
    return this._http.post('/api/getProducts', { headers })
      .catch( (error: any) => Observable.throw(error || 'server error'));
  }

  getProduct(id: number) {
    const headers = new HttpHeaders({'Content-Type': 'application/json' });
    const params = {'id': id};
    return this._http.post('/api/getProduct', { headers, params})
      .catch( (error: any) => Observable.throw(error || 'server error'));
  }
}

这里我从 mongodb 集合 catalog.component.ts 中获取数组:

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

@Component({
  selector: 'app-catalog',
  templateUrl: './catalog.component.html',
  styleUrls: ['./catalog.component.css']
})
export class CatalogComponent implements OnInit {
products: any;
respuesta: any;


  constructor( private mongo2Service: Mongo2Service) {}

  ngOnInit() {
  this.getProducts();

  }

  getProducts() {

    this.mongo2Service.getProducts().subscribe(respuesta => {
      this.respuesta = respuesta;
      this.products = this.respuesta.response.data;
      console.log(this.respuesta);
    });
  }
}

然后我会显示 mongodb 集合 collection 在此列表中: list

我将路由器链接添加到目录组件中的该列表,并将所选元素的 ID 添加到另一个名为“details”的组件中,该组件在 api 和服务中有一个“getProduct”方法,但视图不显示元素的名称或编号:

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;
  products:any;

    constructor(private location: Location,
    private route: ActivatedRoute,
   ,private mongo2Service: Mongo2Service) { }

  ngOnInit() {
  this.getProduct();
  }


  getProduct() {
    const id=+ this.route.snapshot.paramMap.get('_id');
    console.log('entro funcion componente');

    this.mongo2Service.getProduct(id).subscribe(respuesta => {
      this.respuesta = respuesta;
      this.products = this.respuesta.response.data; 
      console.log(this.respuesta);
    });
  }

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

【问题讨论】:

  • .find({ id: new ObjectID(req.query.id) }) 应该是 .find({ _id: new ObjectID(req.query.id) })。那是_id 而不是id 作为ObjectId 的主键检查您的输入并确保您发布的有效查询参数实际上提供了应该匹配的内容。如果仍然不确定,请显示您希望匹配的文档以及请求中实际发送的参数。
  • 你能从req.query.id得到id吗?试试console.log(req.query.id) >
  • 是的,我在运行details组件时可以看到路由上的id

标签: node.js angular mongodb express angular4-httpclient


【解决方案1】:

我解决了,我编辑了 api.js 中的 getProduct 方法,方法是在 find.() 中将 req.query._id 更改为 req.body.id,如您所见:

router.post('/getProduct',(req, res) => {
  var find={ id: new ObjectID(req.body.id) };
  console.log(find);
  connection((db) => {
    db.collection('products')
      .find({_id:new ObjectID(req.body.id)})
      .toArray()
      .catch((err)=>{
        sendError(err, res);
        response.message ={ success:"Se obtuvieron los registros correctamente", error:""};
        res.send({response});
      })
      .then((result)=>{
        response.data= result;
        res.send({response});
      });
  });
});

我还删除了 const id 处的“+”,并在数据中的位置 [0] 详细信息中添加了另一个变量 (product:any)。

 getProduct() {

    const id = this.route.snapshot.paramMap.get('_id');

    console.log(id);
    this.mongo2Service.getProduct(id).subscribe(respuesta => {
      this.respuesta = respuesta;
      this.product = this.respuesta.response.data[0];
      console.log(this.respuesta);
    });
  }

【讨论】:

  • 好收获!! +1 投票所以你在两个地方做错了。 1. 在查找查询中 [将 id 更改为 _id](就像我在下面的答案中解释的那样)和 2. 在 getProduct() 函数中。
  • 另外,您应该添加长度检查以避免 this.respuesta.response.data 出现错误。例如。 if (this.respuesta.response.data.length) { this.product = this.respuesta.response.data }
【解决方案2】:

MongoDB 创建 _id 而不是 id,您的匹配条件对于获取结果是错误的。

我已经更新了查询并添加了控制台日志,如果您现在得到预期的结果,请检查控制台。

    router.post('/getProduct',(req, res) => {
      connection((db) => {
        db.collection('products')
          .find({_id:new ObjectID(req.query.id)})
          .toArray()
          .catch((err)=>{
            sendError(err, res);
            response.message ={ success:"Se obtuvieron los registros correctamente", error:""};
            res.send({response});
          })
          .then((result)=>{

            console.log("Expected Results: ", result);

            response.data= result;
            res.send({response});
          });
      });
    });

这应该会为您提供单个产品的详细信息。在此处检查您如何使用返回的数据。

【讨论】:

  • 谢谢,我在你告诉我的地方更改了 _id 的 id,但控制台日志显示一个空数组,如下所示:“预期结果:”[]
  • 能否重新检查获取到的ID是否在产品集合数据库中>>_id字段?
  • 好吧,我的数据库中有一个 _id,但我无法在响应中得到它
  • 这对您没有帮助吗?我的意思是 _id 和 id 的东西,你在 db.collection('products') .find({_id:new ObjectID(req.query.id)}) ??
猜你喜欢
  • 2017-07-24
  • 2015-07-28
  • 1970-01-01
  • 1970-01-01
  • 2015-01-16
  • 1970-01-01
  • 2017-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多