Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to convert array to cursors in publish?

Tags:

meteor

the following code:

Meteor.push("svse",function(){   
   if(UserUtils.isAdmin(this.userId)) //is Administrator?
       return Svse.find();
   var arr = ["1","1.2"]; //just a example
   var nodes = Svse.find({sid:{$in:arr}}).fetch();
   var newNodes = new Array();
   for(i in nodes){
       var newNode = nodes[i];
       newNode["son"] = ArrayUtils.intersect(arr,newNode["son"]);
       newNodes.push(newNode)
    }
    return newNodes;
});

ArrayUtils={};
Object.defineProperty(ArrayUtils,"intersect",{
value : function(a,b){
    var ai=0;
    var bi=0;
    var result = new Array();
    while( ai < a.length && bi < b.length ){
        if(a[ai] < b[bi] ) {
            ai++;
        } else if(a[ai] > b[bi] ){
            bi++; 
        } else {
            result.push(a[ai]);
            ai++;
            bi++;
        }
    }
    return result;
}
});

at meteor startup results in errors:

 Exception from sub ac338EvWTi2tpLa7H Error: 
      Publish function returned an array of non-Cursors

how to convert array to cursors? or handle array just like ArrayUtils.intersect() in find query operate here?

like image 210
L.T Avatar asked Oct 29 '13 03:10

L.T


1 Answers

It think Meteor.push is a typo in your first line of code.

A publish function needs to return a Collection cursor or an array of Collection cursors. From docs:

Publish functions can return a Collection.Cursor, in which case Meteor will publish that cursor's documents to each subscribed client. You can also return an array of Collection.Cursors, in which case Meteor will publish all of the cursors.

If you want to publish what is in newNodes and don't want to use a collection on the server side then use this.added inside of publish. For example:

Meteor.publish("svse",function(){  
  var self = this;
  if(UserUtils.isAdmin(self.userId)) //is Administrator?
    return Svse.find();  // this would usually be done as a separate publish function

  var arr = ["1","1.2"]; //just a example
  Svse.find({sid:{$in:arr}}).forEach( function( newNode ){
    newNode["son"] = ArrayUtils.intersect(arr,newNode["son"]); //is this just repeating query criteria in the find?
    self.added( "Svse", newNode._id, newNode ); //Svse is the name of collection the data will be sent to on client
  });
  self.ready();
});

It is a bit tough for me to follow what you expect to happen with both the find and intersect functions populating newNode. You might be able to do the same just using find with a limiting the fields returned.

like image 115
user728291 Avatar answered Nov 15 '22 09:11

user728291