juanp_1982
juanp_1982

Reputation: 1007

how to push data back to client in meteor?

I have to make a aggregate query to DB when the user click on a button, however I don't know how to return that result back to the client since I'm doing an asynchronous request, this is part of my code:

//Server side
Meteor.startup(function() {
    Meteor.methods({
        getAllTotals: function (query){
            var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;
            var error = result = match = pipeline = '';
            var group = {
              $group: {
                  _id: null,
                  wall_clock: {
                      "$sum": "$wall_clock"
                  },
                  mem:{
                      "$sum": "$mem"
                  },
                  cpu:{
                      "$sum": "$cpu"
                  },
                  io:{
                      "$sum": "$io"
                  },
                  vmem:{
                      "$sum": "$vmem"
                  },
                  maxvmem:{
                      "$sum": "maxvmem"
                  }
              }
           };

          if(typeof query.submission_time !== "undefined"){
              match = {"$match": {submission_time: query.submission_time}};
              pipeline = [match, group];
          }else{
              pipeline = [group];
          }

          db.collection("GE_qstat_job_monitor").aggregate(
              pipeline,
              Meteor.bindEnvironment(
                  function (error, result){
                      console.log(result); // <<--- this is OK!
                  },
                  function(error) {
                      Meteor._debug( "Error doing aggregation: " + error);
                  }
              )
          );
          return result; // <<--- this is empty
        }
    });
}

any suggestion? :-)

Upvotes: 1

Views: 404

Answers (2)

Kuba Wyrobek
Kuba Wyrobek

Reputation: 5273

Short answer:

Solution you can find here:

Detailed answer

using Meteor._wrapAsync

 var aggregateTotal = function(callback){
      var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;

      // ...

      db.collection("GE_qstat_job_monitor").aggregate(
              pipeline,
              function (error, result){
                if(error){
                   callback(error);
                }else{
                   callback(null, result);
                }
              }
      );
  }

  var aggregateTotalsSync = Meteor._wrapAsync(aggregateTotal);

  Meteor.methods({
      'getAllTotals': function(){
          var result;
          try{
               result = aggregateTotalsSync();
          }catch(e){
              console.log("getAllTotals method returned error : " + e);
          }finally{
              return result;
          }
      }
  });

using Futures (meteorPad example)

//Server side
Meteor.startup(function() {
    var Future = Npm.require('fibers/future');
    Meteor.methods({
        getAllTotals: function (query){
          var fut = new Future();
          var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db;

          // ...

          db.collection("GE_qstat_job_monitor").aggregate(
              pipeline,
              Meteor.bindEnvironment(
                  function (error, result){
                     if(error){
                       fut.throw(error);  
                     }else{
                       fut.return(result)
                     }
                  },
                  function (exception){
                     // caught exception is passed to this callback
                     fut.throw(exception);
                  }
              )
          );
          return fut.wait();
        }
    });
}

Upvotes: 1

Vincent J
Vincent J

Reputation: 801

Easy but a bit dirty way (but not so much if you think well about your architecture) -> send back the result trough Mongo. You can even do it without Meteor.methods, with the request creation inserted in the database on the client, an observer on the server that check it and does the async task, and then write back the result in the database.

Upvotes: 0

Related Questions