I wanted to work with Shopify's address library. Since these work with promises I thought about implementing callbacks in order to receive the results
import { Template } from 'meteor/templating';
import { ReactiveDict } from 'meteor/reactive-dict'
import AddressFormatter from '@shopify/address';
import './main.html';
const address = {
company: 'Shopify',
firstName: '恵子',
lastName: '田中',
address1: '八重洲1-5-3',
address2: '',
city: '目黒区',
province: 'JP-13',
zip: '100-8994',
country: 'JP',
phone: '',
};
Template.hello.onCreated(function () {
const addressFormatter = new AddressFormatter('ja');
const instance = this
instance.state = new ReactiveDict()
instance.state.setDefault('result', {
"formattedAddress": "",
"orderedFields": ""
});
getData(addressFormatter, function(r) {
// the next line triggers the helper, since it "observes" the changes
// to this "result" property on the reactive-dictionary
instance.state.set('result', {
formattedAddress: r.formattedAddress,
orderedFields: r.orderedFields
});
});
})
Template.hello.helpers({
address: function() {
console.log(Template.instance().state.get("result"));
return Template.instance().state.get('result')
}
});
function getData(addressFormatter, callback) {
const fa = async () => {
const result = await addressFormatter.format(address);
console.log(result)
return result;
}
const of = async () => {
const promise = addressFormatter.getOrderedFields('CA');
promise.then(result => {
console.log(result);
return result;
});
}
let results = {
"formattedAddress": fa(),
"orderedFields": of()
}
callback(results);
}
The only thing that I receive in the template are [object Promise]
. The console.logs in the getData() method actually show the accurate data but they are not displayed in teamplte. What can I do to receive the values and make my helper wait for them?
Edit: I have edited it according to @Jankapunkt answer but the objects are still empty, while the results in getData() are not.
You don't. Helpers are there to immediately return values but are triggered by reactive data sources.
If you want a helper to "run" once the data "arrived" then your should move this code into onCreated
and store the value in a reactive data source:
import { Template } from 'meteor/templating';
import { ReactiveDict } from 'meteor/reactive-dict'
import AddressFormatter from '@shopify/address';
import './main.html';
const address = {
company: 'Shopify',
firstName: '恵子',
lastName: '田中',
address1: '八重洲1-5-3',
address2: '',
city: '目黒区',
province: 'JP-13',
zip: '100-8994',
country: 'JP',
phone: '',
};
Template.hello.onCreated(function () {
const instance = this
instance.state = new ReactiveDict()
instance.state.setDefault('result', {
"formattedAddress": "",
"orderedFields": ""
})
const addressFormatter = new AddressFormatter('ja')
getData(addressFormatter)
.then(({ formattedAddress, orderedFields }) => {
// the next line triggers the helper, since it "observes" the changes
// to this "result" property on the reactive-dictionary
instance.state.set('result', { formattedAddress, orderedFields })
})
.catch(e => console.error(e))
return results;
})
Template.hello.helpers({
address: function() {
return Template.instance().state.get('result')
}
});
const getData = async function (addressFormatter) {
const formattedAddress = await addressFormatter.format(address)
const orderedFields = await addressFormatter.getOrderedFields('CA')
return {
formattedAddress,
orderedFields
}
}
Readings: http://blazejs.org/
Edit: added a simplified getData
that should work