Kodie Grantham
Kodie Grantham

Reputation: 2032

How to make calls from the client to the server synchronously?

I'm making several calls from the client to the server depending on a few things and I need them to wait until the one before it has finished and returned a value before the next one starts. Here's a small example of what I'm doing currently:

Client:

function doOrder() {
  var addDevices = Template.instance().addDevices.get();

  if (addLicense) {
    createCustomer();
  }

  if (addDevices) {
    var maintProrate = Session.get('maintProrate');
    var deviceCharge = (deviceFee * addDevices);
    doCharge(deviceCharge, 'DEVICES', 'deviceCharge', 'chargeMaintFee');
  }
}

function createCustomer() {
  var stripeArgs = Helpers.client.stripeArgs('form');

  Meteor.call('stripe', 'customers', 'create', stripeArgs, function(err, response){
    if (err) {
      console.log(err);
      Bert.alert(err, 'danger');
    } else {
      Session.set('customerInfo', response);
      Session.set('customerId', response.id);
    }
  });
}

function doCharge(amount, description, storeKey) {
  var chargeArgs = {
    amount: amount,
    currency: 'usd',
    customer: Session.get('customerId'),
    description: description
  };

  Meteor.call('stripe', 'charges', 'create', chargeArgs, function(err, response){
    if (err) {
      console.log(err);
      Bert.alert(err, 'danger');
    } else {
      Session.set(storeKey, response);
    }
  });
}

Server:

Meteor.methods({
  stripe(func1, func2, arg1) {
    check( func1, String );
    check( func2, String );
    check( arg1, Match.OneOf(Object, String));

    var func = Meteor.wrapAsync(Stripe[func1][func2], Stripe[func1]);
    return func(arg1, {});
  },
  stripe2(func1, func2, arg1, arg2) {
    check( func1, String );
    check( func2, String );
    check( arg1, Match.OneOf(Object, String));
    check( arg2, Match.OneOf(Object, String));

    var func = Meteor.wrapAsync(Stripe[func1][func2], Stripe[func1]);
    return func(arg1, arg2, {});
  }
});

So in the case that addLicense and addDevices are both set during the doOrder function, both createCustomer and doCharge will be ran. What I need is for the createCustomer function to finish and return a value before the doCharge function is ran.

I know that I could place the doCharge function in the callback of the createCustomer function but I have many more functions that need to be ran in order so I'd like to avoid callback hell.

I used Meteor.wrapAsync thinking that would do it but no dice. I still get return values from the API but they all happen at the same time.

Any ideas? Thank you in advance.

Upvotes: 2

Views: 157

Answers (1)

Kodie Grantham
Kodie Grantham

Reputation: 2032

So as @MichelFloyd suggested I ended up moving all of my calls into a server-side method so that only one call from the client is required.

Upvotes: 1

Related Questions