0

I am returning results from a collection with the second result dependent on the first. So, I find resultA, and resultB has to be anything not equal to result A.

My console.log statement shows the data that I want, however, when I return it, nothing shows up in my handlebars template. Nothing returns even if I JSON.stringify it.

myCollection.find({}, {limit:1, skip: _.random(minimum, maximum)}).forEach(function(a){

        myCollection.find({'': {$ne: a._id}}, {limit:1}).forEach(function(b){

            console.log({resultA: a, resultB: b})

            return {resultA: a, resultB: b};        

        });

    });

What am I doing wrong here?

Now I have tried using deps.autorun just incase the collections aren't ready (which they are because console.log always works)

Template.votes.helpers({
twoItems: function(){
    var minimum = 0;
    Deps.autorun(function(){
        var maximum = (Items.find().fetch().length) - 1;

        if (maximum){
            var itemA = Items.find({}, {limit:1, skip: _.random(minimum, maximum)}).fetch()[0];
        }

        if(itemA){
            console.log(itemA);
            var itemB = Items.find({'': {$ne: itemA._id}}, {limit:1}).fetch()[0];   
        }

        if (itemB) {
            data = {itemA:itemA, itemB:itemB};
            console.log(data);
            return data;
        }
    });
},});

with a simple template:

<template name="votes">
<p>Test</p>
<hr>
{{twoItems}}
<hr></template>

At the very least it should return Object but nothing. Console.log always returns the correct data but nothing shows up in the rendered handlebars templates.

Edit: I ended up having to use the following:

    twoItems: function(){
    var minimum = 0;
    var maximum = (Items.find().fetch().length) - 1;
    var itemA = Items.find({}, {limit:1, skip: _.random(minimum, maximum)}).forEach(function(a){
        Session.set('itemAid', a._id);  
    });

    var itemA = Items.find({'_id': Session.get('itemAid')}).fetch()[0];
    var itemB = Items.find({'_id': {$ne: Session.get('itemAid')}}, {limit:1,skip: _.random(minimum, maximum - 1)}).fetch()[0];

    return {itemA: itemA, itemB: itemB};
},

I still don't know why call backs aren't able to return anything. In the docs it says

If you include a callback function as the last argument [In a Meteor.Call] (which can't be an argument to the method, since functions aren't serializable), the method will run asynchronously: it will return nothing in particular and will not throw an exception.

So I'm assuming that since a collection operation is a meteor call as well, then that is why the returns are being ignored.

4

1 回答 1

1

我可以通过包装我在 Deps.autorun 中的一些工作模板帮助程序来复制这个问题,正如你所说 - 控制台日志显示它运行但浏览器中没有任何内容。

一个更标准的写法可能是:

Deps.autorun(function(){
  var itemA, itemB;
  var minimum = 0;
  var maximum = (Items.find().fetch().length) - 1;

  if (maximum){
    itemA = Items.findOne({}, {skip: _.random(minimum, maximum)});
  }

  if(itemA){
    console.log(itemA);
    itemB = Items.findOne({ _id: {$ne: itemA._id}});   
  }

  if (itemB) {
    var data = {itemA:itemA, itemB:itemB};
    console.log(data);
    Session.set( "twoItems", data);
  }
});

Template.votes.helpers({
  twoItems: function(){
    return Session.get( "twoItems" );
  }
});

我希望这会在运行时在您的浏览器中显示“[object, object]”,但我认为您正在期待这一点,并且一旦返回某些内容就会更改模板调用。

同样在您的模板中,您的最后一个<hr>应该是</hr>.

于 2013-07-25T09:32:04.743 回答