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
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);
}
}
});
robfallows:
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); } } });
geez, this stuff is complicated !
hum, i still get
#fhiuw8TypeError: Meteor.callPromise is not a function
with that approach.
And you did do meteor add deanius:promise
?
ah no, so can’t use native promise lib?
thought I just need
import { Promise } from 'meteor/promise';
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.
1 Like
no error but still get this crap instead of the value from url.shorten.
easy fix?
do I still need to involve a reactivevar array if I try that?
DOH!
Yes - the helper won’t re-run without a reactive variable in there!
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!
Any particular reason? That’s the “go to” place for template reactive variables.
BTW, you’re building url
, but never using it.
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!
maybe I need to stick them all in the template.instance reactivevar?
ah or maybe uses const self = this
ah yeah, I think it’s because the data isn’t loaded yet.
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!
1 Like