【问题标题】:Retrieving data from MongoDB causes "Cannot read property 'firstname' of null" error"从 MongoDB 检索数据导致“无法读取属性 'firstname' of null”错误”
【发布时间】:2020-12-09 00:55:37
【问题描述】:

我一直在尝试返回一些用户信息并通过 HTML 显示它们。但我收到错误: “无法读取属性 'firstname' of null”错误” 为了存储数据,我使用 MongoDB,用于后端服务 Express 和 Node.js 以及用于前端 Angular。 为了在后端和前端之间进行通信,我将其委托给了 HttpClient。与 Mongo 的连接工作正常,因为我的控制台接收到所有数据,但是当涉及到前端时,它给了我这个问题。

连接MongoDB的routes-index.js类方法

router.get('/tasks', async (req, res) => {
let MongoClient = require('mongodb').MongoClient;
var url = "mongodb://localhost:27017/";
res.json([
    MongoClient.connect(url, function(err, db) {
        if (err) throw err;
        var dbo = db.db('angular-auth');
        dbo.collection('users').find({}).toArray(function(err, result) {
            if (err) throw err;
            console.log(result);
            //db.close;
         });
      })
   ])
 });

tasks.service.ts 向前端返回数据的类方法

getTasks() {
return this.httpClient.get<any>(this.URL + '/tasks');
}

private-tasks.component.ts 类 ngOnInit() 方法,假设获取和订阅数据

ngOnInit(): void {
this.tasksService.getTasks()
  .subscribe(
    res => {                             
      console.log(res);    //<===== this line is returning null value!
      this.tasks = res;                  
    },
    err => console.log(err)
  );
}

private-tasks.component.html 类

<ul class="list-group">
 <li class="list-group-item" *ngFor='let task of tasks'>
  {{task.firstname}}
 </li>
</ul>

console.log(res);给出空值,但在 if/else 语句中它实际上不是空的……我怎么确定那不是……因为同样的方法在控制台中给了我输出。我也尝试过添加? {{task?.firstname}} 以这种方式我没有收到任何错误,但仍然是 console.log(res);给出空值。

您有什么建议可以解决这个问题吗?

【问题讨论】:

    标签: node.js angular mongodb express


    【解决方案1】:

    罪魁祸首是后端的res.json 调用。代码的前端看起来不错。函数调用的参数应该是您从服务器返回到客户端的对象,但是如果 MongoClient.connect 返回什么,您将给它什么 - 这可能什么都没有(我从未使用过它所以我不能确定)。

    你调用console.log的地方在最里面的回调函数里面。在这段代码运行的那一刻,数据库已经响应并且可以将响应发送给客户端。但是您尝试在此回调运行之前将数据发送到客户端。

    所以正确的做法是将res.json放在最里面的回调中,当数据可用时运行。

    MongoClient.connect(url, function(err, db) {
      if (err) throw err;
      var dbo = db.db('angular-auth');
      dbo.collection('users').find({}).toArray(function(err, result) {
        if (err) throw err;
        console.log(result);
        res.json(result); // <-- res.json goes inside, after data is available
      });
    });
    

    【讨论】:

    • 拉扎尔,你是上帝! “但是您尝试在运行此回调之前将数据发送到客户端”我怀疑这是实际问题,因为 console.log(res) 给了我 null,但在终端中,我可以看到数据!最后,console.log(res) 返回所有用户。尽管如此,什么都没有显示,但我会找到解决它的方法
    【解决方案2】:

    这听起来像是一个异步问题,您可以在 service.ts 文件中尝试以下内容:

    1. 您将需要某种 mongo 模型来保存数据。例如:
     private tasks:TaskModel[] = []
    
    1. 除了模型之外,您还需要一个需要从 rxjs 导入的主题。
    import {Subject} from 'rxjs';
    

    private taskUpdated = new Subject<taskModel>[](); //create a new subject of type taskModel that you will add to
    
    1. service.ts 文件中要更新的最后一点是:
    getTasks(){
       this.httpClient.get<any>(this.URL + '/tasks')
       .subscribe((taskData)=> {
           this.taskNotes = taskData;
           this.taskUpdated.next([...this.taskNotes])//adding in taskNotes
    })
    
    getTasksUpdatedAsListener(){
       return this.taskUpdated.asObservable();//observable that you will subscribe to in component.ts
    }
    
    1. 然后在您的 component.ts 文件中,您将创建另一个订阅对象并将您的代码更改为:
    //subscription that needs to be created
    private sub:Subscription;
    
    
    
    ngOnInit(): void {
        this.tasksService.getTasks()//this needs to go first. It will get data in the service file
    
        this.sub = this.taskService.getTasksUpdatedAsListener()
            .subscribe((data TaskModel[])=> {
               console.log(data);//you should see the data come in as json
            })
    
    
    }
    

    告诉我进展如何!

    【讨论】:

    • Jexon 感谢您的努力!我会尝试,但这看起来对我没有太大帮助:) 我刚刚开始学习 Node 和 Angular。顺便说一句,这是 NEST.js 还是 NODE.js?好像是 NEST.js
    • 它是节点,除非我不小心下载了nest.js。让我知道你是否能弄清楚!几个月前我开始学习 Angular 并遇到了这个问题,直到我找到了我展示给你的解决方案。我读到的所有内容都说这是一个异步错误,因此您可能也值得花时间了解更多信息
    猜你喜欢
    • 2012-10-03
    • 1970-01-01
    • 1970-01-01
    • 2015-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-02
    • 2022-09-28
    相关资源
    最近更新 更多