【问题标题】:Cannot insert to collection from NPM using Meteor 1.3无法使用 Meteor 1.3 从 NPM 插入集合
【发布时间】:2016-07-30 17:23:20
【问题描述】:

我正在使用 imap-simple NPM 包检查电子邮件,但无法让插入正常工作。

我已经阅读了这个页面:https://guide.meteor.com/using-npm-packages.html#async-callbacks - 我已经尝试了这些建议,但没有一个有效!

我还稍微简化了代码以尝试使其正常工作,但仍然没有运气。

问题应该很容易复现——meteor npm install imap-simple,把上面的代码扔到服务器上,添加一些email凭证,然后调用方法。

这是我的代码:

var imaps = require('imap-simple');
var config = {
    imap: {
        user: '<removed>',
        password: '<removed>',
        host: 'imap.gmail.com',
        port: 993,
        tls: true,
        authTimeout: 3000
    }
};

Meteor.methods({

    api_connectEmail: function () {
        console.log('Received call to connect email');

        imaps.connect(config).then(function (connection) {

            return connection.openBox('INBOX').then(function () {
                var searchCriteria = [
                    'UNSEEN'
                ];

                var fetchOptions = {
                    bodies: ['HEADER', 'TEXT'],
                    markSeen: true
                };

                return connection.search(searchCriteria, fetchOptions).then(function (results) {
                    results.map(function (res) {

                        var subject = res.parts.filter(function (part) {return part.which === 'HEADER';})[0].body.subject[0];
                        console.log("Subject: " + subject);

                        // insert
                        var attributes = {
                            subject: subject
                        };
                        console.log("Attempting to insert to collection...");
                        var newData = TempEmailCollection.insert(attributes);
                        console.log("New Database Entry ID: " + newData);

                    });
                });
            });
        })
    }
});

带有主题的 console.log 正在运行。插入不工作。没有错误,没有 console.log 后插入,什么都没有。

我已经尝试了指南中推荐的两种策略,但都不起作用。

【问题讨论】:

  • 什么是 TempEmailCollection?
  • @Darren 一个专门用于包含邮件信息的 Mongo 集合。通常在 Meteor 的任何地方, .insert 都适用于集合。但不在 NPM 模块上。传统的解决方法对我不起作用。
  • 你需要显示它的代码;整个问题似乎与此有关,而不是电子邮件(您说的有效)
  • @Darren 我想你误会了。在 Meteor 中,集合没有“代码”。创建一个集合只需要一行 - TempEmailCollection = new Mongo.Collection('temp_email');在 Meteor 项目中的任何地方,您都可以操作集合,除了 NPM,它似乎使用不同的光纤。
  • 更具体地说,NPM 模块工作正常。但是范围是错误的 - NPM 无法使用 Meteor 的 mongo 收集功能。我提供的链接解释了如何解决这个问题,但解决方法在这种情况下没有帮助,可能是由于搜索功能的工作原理。

标签: javascript node.js mongodb meteor npm


【解决方案1】:

问题是您在异步调用的 Promise 处理程序中调用 Meteor 函数。 但是,在服务器上调用的所有 Meteor 函数都必须在光纤中运行。 在这种情况下,Meteor 实际上会引发错误,但您忽略了它,因为您没有为 Promises 指定 catch 函数。

考虑以下简化示例(它只是连接到服务器并尝试插入新文档):

import { Meteor } from 'meteor/meteor';
import imaps from 'imap-simple';

const Storage = new Mongo.Collection('storage');

const config = {
  imap: {
    …
  }
};

Meteor.methods({
  connect() {
    console.log('Method called');

    imaps.connect(config).then(function(connection) {
      console.log('Connected');

      Storage.insert({
        value: 'success'
      });

      console.log('Document inserted');
    })
    .catch(function(err) {
      console.error(err);
    });
  }
});

以下消息将到达catch 函数:

[Error: Meteor code must always run within a Fiber. Try wrapping callbacks that you pass to non-Meteor libraries with Meteor.bindEnvironment.]

您可以这样做来包装insert 调用:

Meteor.methods({
  connect() {
    console.log('Method called');

    const insert = Meteor.bindEnvironment(function() {
      Storage.insert({
        value: 'success'
      });
    });

    imaps.connect(config).then(function(connection) {
      console.log('Connected');
      insert();
      console.log('Document inserted');
    })
    .catch(function(err) {
      console.error(err);
    });
  }
});

然后文档将按预期插入。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-22
    • 2016-07-27
    • 2016-07-30
    • 2016-09-07
    • 2016-08-03
    • 2016-10-31
    • 2016-08-16
    • 2016-09-08
    相关资源
    最近更新 更多