DEV Community

Jan Küster 🔥
Jan Küster 🔥

Posted on • Edited on

8 1

Async Meteor Method calls

Meteor is mostly backward compatible to even < 1.0 projects. Therefore lots of code is still callback based. So is the Meteor.call method. You can easily wrap it into a Promise-based approach:

export const callMethod = ({ name, args }) => 
  new Promise((resolve, reject) => {
    Meteor.call(name, args, (error, result) => {
      if (error) {
        return reject(error)
      }

      return resolve(result)
    })
})
Enter fullscreen mode Exit fullscreen mode

Although Meteor.call supports multiple arguments I rather prefer to pass a single object with named arguments to keep the code more expressive.

You can then use callMethod natively in an async environment:

Template.myTemplate.events({
  'click .some-button': async function (event, templateInstance) {
    const age = await callMethod({
      name: 'getAge', 
      args: { name: 'John Doe' }
    })
    console.log(age) // whatever the method returned
  }
})
Enter fullscreen mode Exit fullscreen mode

Additionally you can "hook" into these calls and thus mix callbacks with promises and create a decent UX experience when method calls are part of user interactions:

export const callMethod = ({ name, args, prepare, receive, success, failure }) => {
  // before call
  if (typeof prepare === 'function') {
    prepare()
  }

  // create the promise
  const promise = new Promise((resolve, reject) => {
    Meteor.call(name, args, (error, result) => {
      // on received
      if (typeof receive === 'function') {
        receive()
      }

      if (error) {
        return reject(error)
      }

      return resolve(result)
    })
  })

  // on success
  if (typeof success === 'function') {
    promise.then(success)
  }

  // on error
  if (typeof failure === 'function') {
    promise.catch(failure)
  }

  return promise
}
Enter fullscreen mode Exit fullscreen mode

The code can then be used for example to display a "waiting" indicator:

Template.myTemplate.events({
  'click .update-button': async function (event, templateInstance) {
   const updatedDoc = await callMethod({
     name: 'updateUser', 
     args: { name: 'John Doe', age: 42 },
     prepare: () => templateInstance.state.set('updating', true),
     receive: () => templateInstance.state.set('updating', false),
     failure: er => alert(er),
     success: () => alert('updated')
   })
   // process updatedDoc if desired
})
Enter fullscreen mode Exit fullscreen mode


I regularly publish articles here on dev.to about Meteor and JavaScript. If you like what you are reading and want to support me, you can send me a tip via PayPal.

You can also find (and contact) me on GitHub, Twitter and LinkedIn.

Keep up with the latest development on Meteor by visiting their blog and if you are the same into Meteor like I am and want to show it to the world, you should check out the Meteor merch store.

AI Agent image

How to Build an AI Agent with Semantic Kernel (and More!)

Join Developer Advocate Luce Carter for a hands-on tutorial on building an AI-powered dinner recommendation agent. Discover how to integrate Microsoft Semantic Kernel, MongoDB Atlas, C#, and OpenAI for ingredient checks and smart restaurant suggestions.

Watch the video 📺

Top comments (0)

Jetbrains image

Is Your CI/CD Server a Prime Target for Attack?

57% of organizations have suffered from a security incident related to DevOps toolchain exposures. It makes sense—CI/CD servers have access to source code, a highly valuable asset. Is yours secure? Check out nine practical tips to protect your CI/CD.

Learn more

👋 Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay