1

I have a model model/person

{

  firstName: DS.attr( 'string'),
  lastName: DS.attr( 'string'),
  email: DS.attr( 'string' ),
}

and another model model/project

{

  name:            DS.attr( 'string' ),
  code:            DS.attr( 'string' ),
  startDate:       DS.attr( 'date' ),
  endDate:         DS.attr( 'date' ),
  users : DS.hasMany('person', {async: true}),

}

then i'm retrieving all the projects with as an array which contains ember objects. since the project -> users is async its a promise. and i want to sort that array using the first name of the person. when the data is arrived accordingly and re render the hbs that is using the list

i have a computed property called

renderProjects = computed ('model.projects.[]')
{
 // trying to sort in here but data is not avaiable so its not getting sorted
}

2 Answers2

3

The solution is simply to use .@each:

renderProjects: computed ('model.projects.@each.firstName', function() {
  return this.users.sortBy('firstName');
})

this will recompute the renderProjects CP whenever the list of projects change or any firstName on any of the projects changes and then automagically update your view.

One important notice: You can not do .@each.foo.bar. This is what you did in your twiddle with model.@each.myUser.name.

In your twiddle the easiest fix is to add a computed.alias to the video model:

username: computed.alias('myUser.name'),

Then you can do this:

sortedVideos: computed('model.@each.username', function() {
  return this.get('model').sortBy('username');
})

Here is a fixed twiddle.

Lux
  • 17,835
  • 5
  • 43
  • 73
0

I would implement an observer, which watches the project array. Inside of the observer I would resolve the users-relationship sort the project array subsequently.

Please check out following code snippet.

  modelObserver: observer('model.[]', function() {
    let userPromises = this.get('model').map(project => project.get('users'));
    RSVP.all(userPromises).then(function() {
      this.set('sortedProjects', this.get('model').sortBy('users.firstObject.name'));
    }.bind(this));
  })
wuarmin
  • 3,274
  • 3
  • 18
  • 31
  • thank you for the quick response ! happy to say that it worked. i was not clear how to use promise array on that. using this example it resolved. Thank you again :) – Thilina Dinith Fonseka Nov 22 '18 at 10:02
  • 1
    this is a *really bad* idea! you should *never* use observers to set ember state. Usually there are *very few* reasons to use observers over CPs. – Lux Nov 22 '18 at 10:21
  • 1
    @Thilina Dinith Fonseka. Please checkout Lux's answer. His solution is how it should be in ember, much better. Please unaccept this answer. – wuarmin Nov 23 '18 at 07:34
  • @asdf thank you. i accepted your answer cause it worked for me. i will try lux answer as well. – Thilina Dinith Fonseka Nov 26 '18 at 07:36