【问题标题】:Meteor: sending the document id via emailMeteor:通过电子邮件发送文档 ID
【发布时间】:2016-07-08 12:29:41
【问题描述】:

我有一个依赖于流星电子邮件包的时事通讯。

只要管理员向集合提交新的新闻和事件条目,所有订阅者都会通过电子邮件收到此信息。这也有效。

但是,我想将新闻和事件条目的新具体链接添加到页面。

新闻和活动页面的路线:

// Specific news and events
Router.route('/news-and-events/:_id', {
    name: 'newsAndEventsPage',
    waitOn: function(){
        return [
            Meteor.subscribe('newsevents'),
            Meteor.subscribe('images'),
            Meteor.subscribe('categories'),
            Meteor.subscribe('tags'),
        ]
    },
    data: function(){
    return NewsEvents.findOne({_id: this.params._id});
    },
});

添加新条目的管理路径(表单页面):

// Admin news
Router.route('/admin-news-events', {
    name: 'adminNewsEvents',
    waitOn: function(){
        return [
            Meteor.subscribe('newsevents'),
            Meteor.subscribe('images'),

        ]
    },
    data: function(){
        return false
    },
});

将帖子提交到集合后,我尝试捕获条目并传递 id,但我只是得到未定义。

我的管理员 template.js(已编辑):

'submit form': function (evt, template) {
    evt.preventDefault();

    var temp = {};
    temp.title = $('#title').val();
    temp.description = $('#description').summernote('code');
    temp.type = $('input[name=netype]:checked').val();
    temp.createdAt = moment().format('ddd, DD MMM YYYY hh:mm:ss ZZ');

    Meteor.call('NewsEvents.insert', temp);
    Bert.alert("New entry added.");

    //Fire the email to all Subscribers
    var entry = NewsEvents.findOne(this._id);
    var entryId = entry.id;

    //NOT WORKING
    var news = '<a href='+Meteor.absoluteUrl()+'news-and-events/'+entryId+'></a>';

    for (i = 0; i < Subscribers.find().count(); i++) {
    var email_ = Subscribers.find().fetch()[i].email;
      Meteor.call('sendEmail',
      email_, //To
      'Open Strategy Network <xxx.yyy@zzz.yyy.xx>', //from
      'Open Strategy Network News and Events', //subject
       news);
    }
  }

服务器方法:

   Meteor.methods({
      'NewsEvents.insert': function (doc) {
        if (this.userId) {
          NewsEvents.insert(doc);
        }
      }
     });

...
//Send emails
    'sendEmail': function (to, from, subject, text) {
      // check([to, from, subject, text], [String]);
      this.unblock();
      Email.send({
        to: to,
        from: from,
        subject: subject,
        html: text
      });
    },

非常感谢。

【问题讨论】:

    标签: javascript mongodb meteor


    【解决方案1】:

    .find() 返回一个游标,而不是一个对象。你可以这样做:

    var entry = NewsEvents.findOne(this._id);
    var entryId = entry.id;
    

    或者更简单,因为您已经拥有_id

    var entryId = this._id;
    

    或者更简单:

    var news = '<a style:"text-decoration: none;"
      href='Meteor.absoluteUrl()+'news-and-events/'+this._id+'></a>';
    

    此外,您正在尝试在异步插入时发送电子邮件。

    Meteor.call('NewsEvents.insert', temp); // this might take some time to complete
    
    var entry = NewsEvents.findOne(this._id); // `this` is not going to refer to the just added NewsEvent
    

    相反,在方法的回调中执行通知:

    Meteor.call('NewsEvents.insert', temp, function(err, result){
      if ( !err ){
    
      // assuming that `result` will be the _id of the inserted object!!
        var news = '<a href='+Meteor.absoluteUrl()+'news-and-events/'+result+'></a>';
    
        Subscribers.find().forEach(function(s){
          Meteor.call('sendEmail',
            s.email, //To
            'Open Strategy Network <violetta.splitter@business.uzh.ch>', //from
            'Open Strategy Network News and Events', //subject
             news
          );
        }
      }
    });
    

    你的NewsEvents.insert方法需要返回插入对象的_id

    Meteor.methods({
      'NewsEvents.insert'(doc) {
        if (this.userId) return NewsEvents.insert(doc);
       }
     });
    

    现在,即使是上述内容也会很慢,因为您正在循环中执行Meteor.call()。其次,您已将您的服务器作为邮件中继打开,因为任何人都可以使用sendEmail 方法从您的应用程序内的控制台向任何人发送任何电子邮件。如果您想高效地执行此操作,请将通知代码放入您的 NewsEvents.insert 方法中,并在服务器上完成所有操作,无需所有来回!

    【讨论】:

    • 谢谢。解决方案打印...news-and-events/undefined。此代码在将新文档插入集合之后但在相同的提交表单事件中运行。任何想法为什么它是未定义的?我编辑了我的 template.js 文件。
    • 你能显示你插入的代码,然后尝试获取_id吗?
    • 看起来不错。我明天再试一次。目前Meteor.call('NewsEvents.insert', temp, function (err, result) { if(!err) { console.log("result: " + result); } else { console.log("err: " + err); } }); 没有做任何事情。我想知道为什么。我再次编辑了我的帖子以添加我的方法。
    • return NewsEvents.insert(doc) 似乎还不够?我把这个问题分开了:stackoverflow.com/questions/38292221/…
    【解决方案2】:

    如果我理解正确,您希望获得插入文档的 ID。它相当简单。

    在插入的方法中:

    var docId = Somethings.insert({ //fields here });
    

    现在您可以在发送电子邮件的相同方法中使用该 docId。

    如果你还想把documentId发给客户端,你可以使用error,结果Meteor.call()是这样的:

    Meteor.call('methodName', arg, arg2, function(err, res){
        if(!err){
            //do something with res. in this case the res is inserted docId as I returned docId in the method
            Router.go('/some-route/' + docId)
        } else {
            //do something with err
        }
    });
    

    上面的错误来自你在方法中抛出的错误。对于结果,您需要返回一个可以是插入的 docId 的值:

    return docId
    

    整理方法:

    methodName: function (arg, arg2){
        //equals to err in the `Meteor.call()`
        if(arg !== 'something'){
            throw new Meteor.Error('This is an error')
        }
    
        //insert new document
        var docId = Somethings.insert({
            fieldOne: arg,
            fieldTwo: arg2
        });
    
        //send email to each subscriber. I don't know your exact DB fields so, its up to you. You did this in a different call.
        var cursor = Subscribers.find();
        cursor.forEach(function(ss){
            //send email here. You can use each subscriber data like ss._id or ss.email. However you insert them...
        });
    
    
        //Equals to res in `Meteor.call()`. sends a result to the client side method call. inserted docId in this case
        return docId
    },
    

    PS:如果这不能回答你的问题,那意味着我不明白你想要达到什么目的。给我留言,我会编辑答案。

    编辑

    我使用一种方法来发送电子邮件和插入文档,但您仍然可以像我一样传递错误/结果,然后使用结果中的 id 再次调用电子邮件。

    【讨论】:

    猜你喜欢
    • 2023-03-10
    • 2012-07-14
    • 2017-02-08
    • 1970-01-01
    • 2021-04-10
    • 1970-01-01
    • 2012-01-07
    • 2012-04-27
    相关资源
    最近更新 更多