I'm trying to use a computed property based on the values from an async, hasMany model property, but cannot get it to display in my view.
MyApp.Foo = DS.Model.extend({
title: DS.attr('string'),
peeps: DS.hasMany('peep', { async: true });
});
MyApp.Peep = DS.Model.extend({
name: DS.attr('string'),
email: DS.attr('string')
});
MyApp.Foo.FIXTURES = [
{ id: 1, title: 'nice', peeps: [1,2] }
];
MyApp.Peep.FIXTURES = [
{ id: 1, name: 'mypeep', email: '[email protected]' },
{ id: 2, name: 'mypeep2', email: '[email protected]' }
];
MyApp.FooController = EmberObjectController.extend({
showPeeps: function() {
// This one works for this test data.
// return [{name: 'baz', email: 'bar'}];
var peepList = this.get('content.peeps.[]').then(function(c) {
// This one does not work, even for this test data.
return {name: 'baz', email: 'bar'}];
});
}.property('content.peeps.[]');
});
In my view, something along the lines of:
{#each peep in controller.showPeeps}}{{peep.name}}{{/each}}
I can see all the data in the "then()" using console.log(), and as it indicates in the code comments, it works if I take the return out of the "then()" - but then the real data is empty because it is returned as async. If I try to make it non-async, I get
Uncaught TypeError: Cannot call method 'resolve' of undefined
I've tried many variants of the computed property code (using @each, using model.peeps - all of which correctly show the data in console.log(), but not in the view. In the view, it is always undefined unless I just return dummy data outside of the then() - which displays correctly)
What am I missing?
What are Computed Properties? In a nutshell, computed properties let you declare functions as properties. You create one by defining a computed property as a function, which Ember will automatically call when you ask for the property. You can then use it the same way you would any normal, static property.
A promise can be in one of three states: pending, fulfilled, or rejected. Promises that are fulfilled have a fulfillment value and are in the fulfilled state. Promises that are rejected have a rejection reason and are in the rejected state. A fulfillment value is never a thenable.
Ember Data is also designed to work with streaming servers, like those powered by WebSockets. You can open a socket to your server and push changes into Ember Data whenever they occur, giving your app a real-time user interface that is always up-to-date.
Don't treat the hasMany relationship as a promise, treat it as an array. That's the whole point of DS.PromiseArray
. If you just want the users, don't even bother with the computed property, just use peeps
in your template. But, if you need to convert the data somehow, use map
.
showPeeps: function() {
return this.get('peeps').map(function(peep) {
return { name: peep.name, email: peep.email };
});
}.property('peeps.@each')
Also, don't watch the []
property. That only updates when an item is added or removed from the array. Your array contents aren't changing, the contents of the contents are changing. You should watch the @each
property instead. You also don't need to add []
to the end of the property name, and you don't need to prefix the property with content.
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With