Problem with loading data


#1

Hello,

I’m having problems with loading data from relationship. Data is loaded in local storage (when you open Ember “Data” tab in Chrome Developer Console it’s loaded and in “Network” tab all API request calls are successful), but it’s not returned at first time (when you refresh the page) back to controller and template. Later it shows up, but you need to open page several times until it’s all returned.

This is code for customer model (in this model is relationship):

    export default Model.extend(NonRestAction, {
      ajax: service(),
      customerId: attr('string'),
      name: attr('string'),
      users: hasMany('user', {async: true}),
      orders: hasMany('order', {async: true}),
      ...
    });

Problem is here: users: hasMany(‘user’, {async: true}) - ANNOTATION: I have tried also with async: false, then it shows error: Assertion Failed: You looked up the ‘users’ relationship on a ‘customer’ with id 3 but some of the associated records were not loaded. Either make sure they are all loaded together with the parent record, or specify that the relationship is async (‘DS.hasMany({ async: true })’)

This is code for user model (which is not returned):

export default Model.extend(NonRestAction, {
  ajax: service(),
  firstName: attr('string'),
  lastName: attr('string'),
  emailAddress: attr('string'),
  password: attr('string'),
  locale: attr('string'),
  customer: belongsTo('customer'),
  ....
});

This is code for controller, where data should be loaded:

      filteredUsers: computed('model.users', 'filter', 'searchEnabled', function() {
    const {model, searchEnabled, filter, store} = this.getProperties('model', 'searchEnabled', 'filter', 'store');
    return DS.PromiseArray.create({
      promise: model.get('users').then(users => (users.filter(user => user.get('firstName').toLowerCase().indexOf(filter.toLowerCase()) >= 0
            || user.get('lastName').toLowerCase().indexOf(filter.toLowerCase()) >= 0)))
    });
  })
  • I tried with debugging length of users array: in console show sometimes good length sometimes not. Sometimes it comes twice with 0 or with some other number smaller than real number that should come out.
  • Only after few loadings all user objects are returned.

#2

It’s easier if you can move the data loading into your route.

async model() {
  // This would do whatever you're already doing to load your customer model
  let customer  = await this.findRecord(...);

  // Then immediately load the users
  let users = await customer.get('users');

  // Now you have no more asynchronous loading to deal with, and your controller & template can just use `model.customer` and `model.users`
  return { customer, users };
}
filteredUsers: computed('model.users', 'filter', 'searchEnabled', function() {
  return this.get('model.users').filter(user => ...);
})

#3

@ef4, I thought async/await was not available yet: https://github.com/emberjs/rfcs/issues/175#issuecomment-393605276


#4

It works with some caveats in your tests. But forget I mentioned it, the same idea works if you use normal .then()