[SOLVED] Peek not triggering foo.loading


#1

I’m having an issue where I’m using peekAll() to load a large list of records in my route model(). I’ve got some view rendering streamlining to do as the page render is currently taking 2500ms, but it’s highlighting that the foo.loading state doesn’t seem to be triggered, as the page template hangs on the existing link when the new link is clicked for the 2500ms without loading displaying. How do I manually control the foo.loading state in the route.js file so that the loading template renders?

I’ve got the following code in my route.js file currently trying to use schedule to set isRendering on the controller:

  model(params, transition) {
    const passedInOrgCode = transition.params.customers.org_code;
    const orgCode = passedInOrgCode !== undefined ? passedInOrgCode : this.get('currentUser.org.orgCode');

    if (orgCode !== this.get('currentUser.impersonatedOrg.orgCode')) {
      this.store.queryRecord('organisation', { org: orgCode }).then(org => {
        this.get('currentUser').impersonateOrg(org);
        this.set('title', `Customers - ${this.get('currentUser.impersonatedOrg.tradingName')} - Kordia Portal`);
      });
    } else {
      this.set('title', `Customers - ${this.get('currentUser.impersonatedOrg.tradingName')} - Kordia Portal`);
    }

    const peekData = this.store.peekAll('customer');

    let filterByOrg = (customers) => {
      return customers.filter((item) => {
        if (item.get('parentOrgCode') === orgCode || parseInt(orgCode) === ENV.APP.KORDIA_ORG_CODE) {
          return true;
        }
      });
    };

    if (peekData.get('content').length === 0) {
      return new Ember.RSVP.Promise((resolve, reject) => {
        this.store.query('customer', { orgCode: orgCode }).then((customers) => {
          resolve(filterByOrg(customers));
        }).catch(() => { reject(); });
      });
    } else {
      Ember.run(() => {
        this.controllerFor('customers.index').set('isRendering', true);
        return filterByOrg(peekData);
      });
      Ember.run.schedule('afterRender', () => {
        this.controllerFor('customers.index').set('isRendering', false);
      });
    }

  },

And in my handlebars file:

{{#if isRendering}}
  {{loading-component }}
  {{else}}
  {{customer-list customers=model updated=updated search=search orgCode=orgCode}}
{{/if}}

All of the states are triggering to the console with the right timing, but I can’t get the view to render the loading state.


#2

[SOLVED]

I had to wrap my peekAll in a RSVP promise object with an Ember.run.later function. The answer was in the Asynchronous Routing docs - https://guides.emberjs.com/v2.12.0/routing/asynchronous-routing/#toc_the-router-pauses-for-promises. The relevant piece of code is below:

    if (peekData.get('content').length === 0) {
      return new Ember.RSVP.Promise((resolve, reject) => {
        this.store.query('customer', { orgCode: orgCode }).then((customers) => {
          resolve(filterByOrg(customers));
        }).catch(() => { reject(); });
      });
    } else {
      return new Ember.RSVP.Promise(function(resolve) {
        Ember.run.later(function() {
          resolve(filterByOrg(peekData));
        });
      });
    }

Hope this helps someone :slight_smile: