[SOLVED] Two method-calls relying on each other


#1

I have two Insert Method calls from a form that inserts into two separate collections like so:

/*
    *	Show
    */
    var selectedShow = Session.get('selectedShow');
    if(selectedShow) {
      var show = {
        name: selectedShow.collectionName,
        uniqueShowId: selectedShow.trackId,
        country: selectedShow.country,
        primaryGenre: selectedShow.primaryGenreName,
        genres: selectedShow.genres
      };

      // insert
      Meteor.call('insertShow', show, function(error, result) {
        if(error) {
          return alert(error);
        }
        if(result) {
          //
        }
      });
    }

And, like so:

/*
    *	Episode
    */
    var selectedEpisode = Session.get('selectedEpisode');
    if(selectedEpisode) {
      var episode = {
        title: selectedEpisode.title[0],
        summary: ((selectedEpisode['itunes:summary']!==undefined) ? selectedEpisode['itunes:summary'][0] : " "),
        duration: ((selectedEpisode['itunes:duration']!==undefined) ? selectedEpisode['itunes:duration'][0] : " "),
        webUrl: ((selectedEpisode.link!==undefined) ? selectedEpisode.link[0] : " "),
        showId: '',
        showName: ''
      };

      // insert
      Meteor.call('insertEpisode', episode, function(error, result) {
        if(error) {
          return alert(error);
        }
        if(result) {
          //
        }
      });
    }

But I want the calls to be synchronous, meaning that I want showId and showName to be populated with the results from the first Method call to insert show. How do I do this? I know I can bundle the methods into one server method call, but I would prefer to keep insertEpisode and insertShow separate. I’ve been looking at Meteor.wrapAsync() and Fibers all day today, but they seem to only be server-side so that doesn’t help. Any tips?


#2

What is insertShow supposed to return? It seems showName, at least, doesn’t need to be returned by any method call, as it is stored in selectedShow


#3

insertShow now returns the following:

// success
    return {
      _id: showId,
			name: show.name
    };

Naming is true, that’s in the Session variable, but how do I handle the ID that MongoDB returns?


#4

See here for how to use synchronously an _id generated by Mongo.Collection.insert.


#5

I like to use meteor promises. Here is an example case I used it in: creating a new user, registering their card with stripe, and creating an initial order.

var order = Orders.findOne();
Meteor.promise('Users.createFromProfile', profile, 'player')
.then(function (user) {
  return Meteor.promise('Stripe.register', user);
})
.then(function (card) {
  return Meteor.promise('Order.create', order, card);
})
.catch(function (error) {
  sAlert.error(error.message);
})

#6

Thank you so much Steve! Took me quite a while to figure this out. I see your point in that other post too about the Meteor.call’s in terms of latency compensation. For calls like this …

insertShow: function(attributes) {

    // author
    var author = Meteor.user();

    // extend attributes
    var show = _.extend(attributes, {
        authorId: author._id,
        authorName: author.profile.name,
    });

		/*
		*	Check if Exists
		*/
		// - If it does exist, don't return error, just don't insert new document.
		// - This is to allow for several episodes from the same show.
		var showExistsId = Shows.findOne({uniqueShowId: show.uniqueShowId}, {fields: {'_id': 1, 'name': 1}});

		// Show exists already
		if(showExistsId) {
			return {
				_id: showExistsId,
				name: showExistsId.name,
				exists: true
			};
		}

    var showId = Shows.insert(show, function(error, result) {

      // throw error
      if(error) {
				throw new Meteor.Error(error.error, error.message);
      }
    });

    // success
    return {
      _id: showId,
			name: show.name
    };
  }

… are these recommended to execute client-side? Eg. not calling for a server method? And Thanks so much corvid, I’ve been looking at Promise and will definitely use it once the method callback stack becomes a bit more unvielding.


#7

For anyone looking into this in the future I highly suggest taking a look at the Meteor.call() and Meteor.apply() documentation. Somehow after frantically Googling for two days I did not stumble upon this. Would love a bit more documentation / some more examples on this, for instance where is returnStubValue: true explained / documented?