DockYard / ember-route-action-helper

Bubble closure actions in routes
MIT License
328 stars 48 forks source link

compatibility with liqud-fire #63

Open Leooo opened 7 years ago

Leooo commented 7 years ago

Hello, I dont know if this belongs to this repo or to liquid-fire repo, but we have recurrent issues where we are transitioning between two routes using liquid-fire, and where for some reason Ember looks for actions in the SECOND route corresponding to the route-action calls of the template in the FIRST route. Any Idea of how we could handle such situations? Maybe a hook in route-action to deactivate the actions when we are transitioning, in some wayy??

Thanks,

L

(copy of https://github.com/ember-animation/liquid-fire/issues/578)

AKST commented 6 years ago

Hey so by the looks of the commit d6e511ecc usage of this library is actively being discouraged?

If you look at ember observer this library is in the top 10% of ember libraries. So I think this issue is worth addressing considering how popular this library is. I recently wrote a patch for our own internal fork of the library & open to making a pull request for it, but it basically does the following, and I thought I would share if it helps with addressing this.

My Patch

Create a service with two properties lastStartedTransition, lastEndedTransition & with a computed property to check if the router is still transitioning by checking if lastStartedTransition & lastEndedTransition are not equal. You capture the values of lastStartedTransition by capturing the transition on the router.willTransition event, and you capture the lastEndedTransition on the router.didTransition event by setting the lastEndedTransition to the value of lastStartedTransition.

export default Service.extends({
  getRouter () {
    return getOwner(this).lookup('router:main');
  },

  lastStartedTransition: null,
  lastFinishedTransition: null,

  init (...args) {
    this._super(...args);
    // ignores tidy up
    const router = this.getRouter();
    router.on('willTransition', this.willTransition.bind(this));
    router.on('didTransition', this.didTransition.bind(this));
  },

  willTransition (transition) {
    this.set('lastStartedTransition', transition);
  },

  didTransition () {
    this.set('lastFinishedTransition', this.get('lastStartedTransition'));
  },

  isTransitioning: compute('lastStartedTransition', 'lastFinishedTransition', function () {
    return this.get('lastFinishedTransition') !== this.get('lastStartedTransition');
  }),
})

And in route-action helper, the assertion for the helper is relaxed while the transition is occurring, basically like this

export default Helper.extend({
  // ...

  compute([actionName, ...params]) {
    // ...

    runInDebug(() => {
      let { handler } = getRouteWithAction(router, actionName);
      let isTransitioning = this.get('new-service.isTransitioning');
      assert(
        `[ember-route-action-helper] Unable to find action ${actionName}`,
        handler || isTransitioning,
      );
    });

    // ...
  }
});

Assumptions and potential problems

Assertions are no longer effective on during a transition, but any error will only occur after the transition has finished. However this means no assertion will occur on loading routes or error routes. For liquid fire users the route-action will return null on pages it is transitioning away from, & null checking may be required.