Help with promise.await syntax


#1

sorry I’m a noob trying to get promises to work in a helper

Template.discoverItemPanel.helpers({
  buyUrl: function () {

    let url = 'https://my.domain.com/?pquantity=1'
    url += `&pprice=${this.priceJPY}`
    url += `&plink=${this.productUrl}`
    url += `&pname=${this.productName}`

    return Promise.await(resolve => {
      Meteor.call('url.shorten', this.productUrl, function (err, res) {
        if (err)
          console.log('#fhiuw8' + err);
        else
          resolve(res)

      })
    })

TypeError: Promise.await is not a function

I read this

but I get totally lost because I need a parameter . @robfallows .

tried this

import { Promise } from 'meteor/promise';


export const callWithPromise = (method, myParameters) => {
  return new Promise((resolve, reject) => {
    Meteor.call(method, myParameters, (err, res) => {
      if (err) reject(err);
      resolve(res);
    });
  });
}

Template.discoverItemPanel.helpers({
  buyUrl: async function () {

    let url = 'https://my.domain.com/?pquantity=1'
    url += `&pprice=${this.priceJPY}`
    url += `&plink=${this.productUrl}`
    url += `&pname=${this.productName}`


    return await callWithPromise('url.shorten', 'https://lite.cnn.com');
  }


template yields


#2

Promise.await is a server-side implementation of await that understands about fibers. It’s not available on the client, because the client doesn’t have fibers.

In any case, you can stick with standard async/await on client and server - there’s generally no need to fall back to using Promise.await, although if you’re adding support for async calls into a large server function, it’s a useful tool to avoid refactoring.

If you meteor add deanius:promise to your app, you’ll reduce the boilerplate - I cover all this in that article - and your code ends up something like this:

Template.discoverItemPanel.helpers({
  async buyUrl() {

    let url = 'https://my.domain.com/?pquantity=1'
    url += `&pprice=${this.priceJPY}`
    url += `&plink=${this.productUrl}`
    url += `&pname=${this.productName}`

    try {
      return await Meteor.callPromise('url.shorten', this.productUrl);
    } catch (err) {
      console.log('#fhiuw8' + err);
    }
  }
});


#3

geez, this stuff is complicated !

hum, i still get

#fhiuw8TypeError: Meteor.callPromise is not a function

with that approach.


#4

And you did do meteor add deanius:promise?


#5

ah no, so can’t use native promise lib?


#6

thought I just need
import { Promise } from 'meteor/promise';


#7

You can, but as there’s no promise-enabled Meteor.call, you’d have to roll you own. I’m just looking at your callWithPromise implementation - I can’t see anything obviously wrong there - but I’ve been staring at a screen for 8 hours and maybe just can’t see the obvious.


#8

no error but still get this crap instead of the value from url.shorten.

easy fix?


#9

do I still need to involve a reactivevar array if I try that?


#10

DOH!

Yes - the helper won’t re-run without a reactive variable in there!


#11

but I can’t really use onCreated here.
not sure how to get it all working in a single helper, but I’ll see if Serkan can help!


#12

Any particular reason? That’s the “go to” place for template reactive variables.

BTW, you’re building url, but never using it.


#13

yeah, i’ll use url later after I’m sure it works with a hardcoded url

OK seems we finally got the call working!

We load data in onRendered so I thought .onCreated would happen before there was data.

But now I have a new problem: it seems the values of this (this.priceJPY, etc) somehow get lost in the chain.

import { Promise } from 'meteor/promise';

export const callWithPromise = (method, myParameters) => {
  return new Promise((resolve, reject) => {
    Meteor.call(method, myParameters, (err, res) => {
      if (err) reject(err);
      resolve(res);
    });
  });
}



Template.discoverItemPanel.onCreated(async function () {

  let url = 'https://my.whiterabbitexpress.com/?pquantity=1'
  url += `&pprice=${this.priceJPY}`
  url += `&plink=${this.productUrl}`
  url += `&pname=${this.productName}`
  this.list = new ReactiveVar([]);
  this.list.set(await callWithPromise('url.shorten', url))
}
)

Template.discoverItemPanel.helpers({
  hobbits() {
    return Template.instance().list.get();
  },

this.priceJPY become undefined
https://my.whiterabbitexpress.com/?pquantity=1&pprice=undefined&plink=undefined&pname=undefined

gonna sleep on it!

Thanks so much for the guidance! You’re a scholar and a gentleman!


#14

maybe I need to stick them all in the template.instance reactivevar?

ah or maybe uses const self = this


#15

ah yeah, I think it’s because the data isn’t loaded yet.


#16

I think you can put everything except the “new ReactiveVar” in the helper. Don’t forget that “this” in onCreated is “Template.instance()” in the helper.

Trying to read this on my phone, so may have missed something though!