Aggregation to show a total price

Hi all,
I did the official to-do-list tutorial and managed to adapt this with my custom needs. I added a price for the tasks that I can display on my template. But I can’t show the total price and I don’t understand how could I use aggregate despite reading the forum :
using rawCollection seems easier for me than installing another package called tunguska:reactive-aggregate

It is frustrating because as you imagine, my mongoDB query works on Robo3T and I can’t use it in my project,
Thanks for your help,
Elie

const result = Promise.await(
  Collection.rawCollection()
    .aggregate([pipelines])
    .toArray()
);
1 Like

Hi, thanks for your answer, could you comment a little your code, please ? I am not sure to fully understand where should I use it !

my MongoDB query that works in Robo3t = pipelines

Thanks for yor help, I understand that, but should this function be in the /ui folder, inside a helper? Like that?

Template.mytemplate.helpers({ 
    myValue: function() { 
        const result = Promise.await(
            Collection.rawCollection()
            .aggregate([pipelines])
            .toArray()
        );
 })

Aggregations need to run on server side, not client side. So put that code inside a method that is located somewhere (anywhere) under the ‘server’ directory. And then can call that method from client side (UI) code.

Hi, thanks a lot for your answer, it helped. There is also this link that was usefull:
https://docs.meteor.com/api/methods.html

Now I can display my result on the server side, and I was able to console.log() in the console browser using a Promise. I think it is a good sign, but all I display on the webpage itself is [object Promise]. If you know what I am missing, please comment!

Here’s my code sample in ui inside a helpers:

toDisplay: async function() {

    const methodCall = (methodName, ...args) => 
        new Promise((resolve, reject) => {
            Meteor.call(methodName, ...args, (error, result) => {
                if (error) reject(error);
                else resolve(result);
            });
        });
    const totalFeatures = methodCall('bar')
    let resultToReturn = await totalFeatures.then(function(result) {
        return result
        })
    return resultToReturn
}

Have a great day

To make sure you’re actually returning results from the server side method to your client side code, just add a console.log(result) above this line in your code: if (error) reject(error);

If not, look at this article on how to handle async code in methods. I suggest using the async/await approach:

If the console log shows that the result are actually reaching the client side code, then the problem is probably that you are not using the results in a reactive variable. Don’t really remember what are the options in Blaze for these situations. Maybe somebody that still uses Blaze can help you out.

Thanks again, I could console.log() in the browser’s console the results, so I assumed my problem comes from this Reactive concept of Meteor.

After a lot of time, I re-arranged the code with .onCreated and .helpers, like so:
I chose to use ReactiveDict because I know it’s already in my project’s package.

Template.taskfeatures.onCreated(async function () {
  const methodCall = (methodName, ...args) => 
    new Promise((resolve, reject) => {
      Meteor.call(methodName, ...args, (error, result) => {
        if (error) reject(error);
        else resolve(result);
      });
    });
  const totalFeatures = methodCall('bar')
  let feat = await totalFeatures.then(function(result) {
    return result
  })
  this.state = new ReactiveDict();
  this.state.set('myTotalResults', feat);
});

Template.taskfeatures.helpers({
  priceSum() {
    const inst = Template.instance();    
    return inst.state.get('myTotalResults');
  }
});

but I have the same problems as before, the result is not accessible in the html template.

In the template I also used the .subscriptionsReady to avoid some kind of meteor Exception in template helper visible in the console, like so:

{{#if taskfeatures.subscriptionsReady}}
        <p>{{priceSum}}</p>
    {{else}}
        <p>Loading...</p>
{{/if}}

If you have an idea of what’s going on, please share, cheers