Meteor methods and Promises revisited

Hi there, all I wanted was something like:

Session.set('currentSoundGroup', Meteor.call('get_twin_data', sasString, deviceID));

But thats of course too simple for a client/server situation. So, after searching this forum, stack overflow and elsewhere I am more confused.

On my server I have:

Meteor.methods({
 'get_twin_data': function (SaS, DeviceID) {
        if (Meteor.isServer) {
                    return registry.getModuleTwin(DeviceID, moduleId)
            .then((res) => {
                    console.log('Promise resolved', res.responseBody.deviceId);
                    return res;
                }).catch((e) => {
                    console.log('Promise failed', e);
                    throw new Meteor.Error(500, 'There was an error processing your request');
                });
    }

And on the client I have:

GetSoundGroupTwin = (sasString, deviceID) => {
        return new Promise((success, failure) => {
            Meteor.call('get_twin_data', sasString, deviceID, (error, soundGroup) => {
                if (error) {
                    console.log("Inside error of promise handler");
                    failure(error)
                }
                else {
                    console.log("Inside success of promise handler");
                    console.log(soundGroup);
                    success(soundGroup)
                }
            });
        });
    };

    async handleTwinClick(device) {
        console.log("handleClick for Twin");

        Session.set('currentSoundGroup', 'Looking...');
        const sasString = this.props.device.sas_string;
        const deviceID = this.props.device.device_id;


        this.GetSoundGroupTwin(sasString, deviceID)
            .then((result) => {
                console.log('Twin Fetched: ', result);
            }).catch((e) => {
                console.log('Error: ', error.reason);
            })
    }

First of all, the client code never returns, and no value is passed back.

And secondly, the server states “unhandledRejection Maximum call stack size exceeded”

So, wrapping up, is my approach right, and where is the core problem?

I think you’re over-complicating this. Take a look at this article and its successor.

Hopefully, you’ll be able to strip your code right back :slightly_smiling_face:

Thanks Rob, these are actually the most important articles I have read, and the primary reason for the code to look like it does, not sure why you think I can reduce the amount of code.

This is what I’ve got (I’m using deanius:promise for the async calls):

Server:

Meteor.methods({
  async get_twin_data(SaS, DeviceID) {
    try {
      return await registry.getModuleTwin(DeviceID, moduleId);
    }
    catch (e) {
      console.log('Promise failed', e);
      throw new Meteor.Error(500, 'There was an error processing your request');
    }
  },
});

Client:

async handleTwinClick(device) {
  console.log("handleClick for Twin");

  Session.set('currentSoundGroup', 'Looking...');
  const sasString = this.props.device.sas_string;
  const deviceID = this.props.device.device_id;
  Session.set('currentSoundGroup', await Meteor.callPromise('get_twin_data', sasString, deviceID));
}

Wuaw Rob, this made my day. Thank you so much. This certainly cleaned up some stuff. Thanks again! :slight_smile:

And not forgetting, now it works, and I am getting nice data from server-side calls.

1 Like

This package deanius:promise has been an amazing simplification addition in my app. @robfallows I also used your articles a while back to figure this out. It feels like this should be a core meteor package at some point, does anyone, maybe @storyteller have any advice on how we handle some important packages like this going forward? I guess the package is pretty simple, and may not need any or much maintenance, but it would be great to keep an eye on this package :package:. Is @deanius still around to comment? And big thanks :pray: to @deanius for making this in the 1st place!

1 Like