Why does my function on the server return true but returns false on the client side in Meteor.js

I have hasCompleted function that returns true or false which is in the server file file:

Smaples.helpers({
 hasCompleted(userId) {
    // …
    switch (this.frequency) {
      case Frequency.ONE_TIME:{
        return measures.fetch().every(measure => {

          console.log(
            'measure.hasCompleted(userId)', //  true
            measure.hasCompleted(userId),
          );

          measure.hasCompleted(userId);
        });
      }
    }
   // …
  },
})

But when it comes to the client side the above function returns false.

On the client side using useTracker:

  const hasCompleted = useTracker(
    () => sample.hasCompleted(Meteor.myFunctions.getCurrentUserId()),
  );
  console.log(
    'survey.hasCompleted(Meteor.myFunctions.getCurrentUserId())', // false
    survey.hasCompleted(Meteor.myFunctions.getCurrentUserId()),
  );
  console.log('hasCompleted', hasCompleted); // false

The way I access helpers from the client side, is this wrong?

Attempts

inside hasCompleted I manually return true and the console shows true:

Smaples.helpers({
 hasCompleted(userId) {
    // …
    switch (this.frequency) {
      case Frequency.ONE_TIME:{
        return true; // changed
    }
   // …
  },
})

Also, I thought if

console.log(measure.hasCompleted(userId))

after returning it could be changed, but

console.log(measure.hasCompleted(userId))

still returns true:

Smaples.helpers({
 hasCompleted(userId) {
    // …
    switch (this.frequency) {
      case Frequency.ONE_TIME:{
        return measures.fetch().every(measure => {
          measure.hasCompleted(userId);
          console.log(
            'measure.hasCompleted(userId)', //  true
            measure.hasCompleted(userId),
          );
        });
      }
    }
   // …
  },
})

What am I doing wrong?

Hi, I think what you are doing wrong is the way you spread your functions over the client and server territory.
If you don’t need reactivity, you could just call a method that returns your desired result and have as much processing as possible on the client and the smallest possible batch of data in transfer. Devices today are really powerful.
If you need reactivity, you should subscribe to your relevant data and publish a cursor that returns what you need, which also implies having a proper DB design.
As far as I remember, helpers are specific to Blaze while useTracker is a React hook. Are you using Blaze?

Thank you for your answer.

Actually my project is some part is still Blaze but mostly uses React, so I think like you suggest, I have to use methods not helpers to get boolean value in react component.

You can only call Methods and return the value to the client you cannot call Server code on the client, due to how Meteor works.

Meteor methods can be run on both client and server. If it was on the client, this flag would be true: Methods | Meteor API Docs

You can call a method anywhere, what you cannot do is call server code on the client and that’s why methods exist… what is your point?

My point is the same code in meteor method can be run on both client and server.

Right… but you dont need to run methods on server because you can call server code directly on the server … so it’s completely asinine to run it over the network and add unneeded overhead, but if you wanna do it… like many things in life you can

Not really. You can call a method from an other method. That’s an effecient way to reuse your codes. And I believe it doesn’t go over the network, because there’s no real client here.

Why would you need to do that, the contents of the function inside of the brackets that executed can be called anywhere on the server. You just call it directly. Why make a rpc call? It’s asinine man.

Well, I’m not a fan of copy and paste. There should not be 2 or more blocks of code which are identical. It’s just my opinion, it doesn’t fit everyone.

DRY is a coding practice I think mostly everyone agrees with. You seem to have mixed up dry and what methods are.

function myFunc(){ 
.. do stuff with server side packages...
}

Called directly as myFunc or via a Method as Meteor.call are identical and both use DRY

Besides DRY I favour KISS (Keep it simple, stupid) on all my developments and it is the corner stone of my career. That’s why I wouldn’t use a RPC call when I can just call the function’s internals directly. And that’s why I say it’s foolish to do so.

Calling Meteor.Collection.insert() inside a method is an example of a method calling a method

1 Like