I have tried several versions/attempts to create and return a RSVP.Promise as a param to my template.
All the console.log give reasonable values, so the promises are resolving. The problem I have (which is then also the question) is how to return that resolving values to my template.
Here are the versions I've tried:
// in controller.js
testA: Ember.computed('sessionAccount.account.id', function() {
let _this = this;
let promise = new Ember.RSVP.Promise(function(resolve, reject) {
_this.get('store').findAll('accounts2workgroup').then(function(a2ws) {
let workgroups = [];
a2ws.forEach(function(a2w){
if(a2w.get('rights')>1) {
workgroups.push(a2w.get('workgroup'));
}
});
console.log(workgroups);
_this.set('wgAsAdmin', workgroups); // this works
resolve(Ember.A(workgroups)); //=> [Object] in rendered template
// return workgroups; // no, not that way
});
});
promise.then(function(data) {
console.log('did resolve');
console.log(data);
})
return promise;
}).property('sessionAccount.account.id'),
testB: Ember.computed('sessionAccount.account.id', function() {
return new Ember.RSVP.Promise(function(resolve, reject) {
let workgroups = Ember.ArrayProxy.create([{'label': 'TestB Label'}]);
resolve(workgroups);
});
}),
testC: Ember.computed(function() {
return this.store.findAll('artists2workgroup').then(function(a2ws) {
let workgroups = [];
a2ws.forEach(function(a2w){
if(a2w.get('rights')>1) {
workgroups.push(a2w.get('workgroup'));
}
});
console.log(workgroups);
return workgroups; //=> [Object] in rendered
});
}),
testD: Ember.computed(function() {
return this.store.findAll('workgroup'); // this of course works, but that's not what I want...
}),
in my template I test all my tests like so:
<h4>TestB</h4>
{{#each testB as |wg|}}
{{wg}}<br>
{{wg.label}}<br>
{{/each}}
testB: {{testB}}<br>
testB.length: {{testB.length}}<br>
and all (but the last testD obviously) render to
TestB
testB: [object Object]
testB.length:
though I would expect/want them to show
TestB
<DS.PromiseObject:ember1117>
BB-Promotion
testB: <DS.PromiseObject:ember1117>
testB.length: 1
I know there are ways around that (I can set another property when resolving f.e.), but want to do it the right way and learn how to do this. And I know, that these examples don't make too much sense. That's just the basic functionality, it will be enhanced once I get this running.
First please avoid the explicit promise construction antipattern! Also you don't have to save
this, because you have arrow functions inember-cli. So lets rewrite yourtestA:Now this won't make it work. The problem here is that ember templates are not promise-aware. So you have three options:
modelhook to do async work.ember-promise-helpersfrom the template.If you can't do 1, I recommend to go with 3. For this you need to understand the
PromiseProxyMixin. Inember-datayou have two implementations for this Mixin, thePromiseArrayandPromiseObjectAll
ember-datamethods likefindAll,findRecord,queryor async relationships return aPromiseObject/PromiseArray. So they are both,promiseand regular object. Thepromisepart is useful in the routesmodelhook, and theObject/Arraypart is useful for computed properties. So the easiest way to go for you, is to split your CP into two:This will work, because first
allWorkgroupswill be an empty array/unresolved promise, but then when the promise resolves the array gets updated, and thetestACP will recompute.However you can also manually create a new
PromiseArray:However you should know, that in both cases you won't get any information if the Promise fails!