ui-router-extras icon indicating copy to clipboard operation
ui-router-extras copied to clipboard

End of Life, UI-Router v1.x and $previousState

Open majew7 opened this issue 7 years ago • 11 comments

Hello @christopherthielen,

You just added the END OF LIFE NOTICE (commit 96025cdbec9), explaining that "UI-Router 1.0 now includes all the features of ui-router-extras out of the box".

I'd like to move off ui-router-extras and explore using ui-router v1.0. However we are using $previousState of the Previous State Feature Is there an equivalent in ui-router v1.0? I don't see it; perhaps I'm missing it.

Question) Has $previousState been ported over to ui-router yet? Or will it not be ported? In your README.md, I didn't see an explicit mention.

Any feedback would be helpful. Thanks!

majew7 avatar May 18 '17 01:05 majew7

@majew7 I am facing the same problem. Did you find anything in the new implementation yet?

mathiasmoeller avatar Jun 20 '17 12:06 mathiasmoeller

Hi @mathiasmoeller, I've moved on from the project, so I'm having difficulty recalling everything, but I think I concluded that this Previous State Feature wasn't unique, and thus I just implemented a new service that actually worked better for our domain. I think I tied it together with the ui-router event $stateChangeStart.

majew7 avatar Jun 25 '17 22:06 majew7

Would still love to hear @christopherthielen chime in though.

majew7 avatar Jun 25 '17 22:06 majew7

Could anyone post some code for a noob to deal with this missing previousState feature?

dmeagor avatar Sep 22 '17 11:09 dmeagor

I ported the code to use 1.0 TransitionService and converted it to typescript:

import { StateOrName, StateDeclaration, Transition, TransitionOptions, TransitionService, StateService } from '@uirouter/core';

import * as angular from 'angular';
import IInjectorService = angular.auto.IInjectorService;

interface PreviousMemo {
  state: StateDeclaration;
  params: object;
}

const ngModule = angular.module('ct.ui.router.extras.previous', ['ct.ui.router.extras.core', 'ct.ui.router.extras.transition']);

function PreviousStateService($state: StateService, $q: angular.IQService, $transitions: TransitionService) {
  let previous: PreviousMemo = null;
  let lastPrevious: PreviousMemo = null;
  const memos: { [key: string]: PreviousMemo } = {};

  $transitions.onStart({}, function ($transition$: Transition) {
    const fromState = $transition$.from().$$state();

    function commit() {
      lastPrevious = null;
    }

    function revert() {
      previous = lastPrevious;
    }

    if (fromState) {
      lastPrevious = previous;
      previous = {
        state: $transition$.from(),
        params: $transition$.params('from'),
      };

      $transition$.promise.then(commit)['catch'](revert);
    }
  });

  const $previousState = {
    get: function (memoName: string) {
      return memoName ? memos[memoName] : previous;
    },
    set: function (memoName: string, previousState: StateOrName, previousParams: object) {
      memos[memoName] = { state: $state.get(previousState), params: previousParams };
    },
    go: function (memoName: string, options: TransitionOptions) {
      const to = $previousState.get(memoName);
      if (!to) {
        return $q.reject(new Error('no previous state ' + (memoName ? 'for memo: ' + memoName : '')));
      }
      return $state.go(to.state, to.params, options);
    },
    memo: function (memoName: string, defaultStateName: string, defaultStateParams: object) {
      memos[memoName] = previous || { state: $state.get(defaultStateName), params: defaultStateParams };
    },
    forget: function (memoName: string) {
      if (memoName) {
        delete memos[memoName];
      } else {
        previous = undefined;
      }
    }
  };

  return $previousState;
}
PreviousStateService.$inject = ['$state', '$q', '$transitions'];

ngModule.service('$previousState', PreviousStateService);

ngModule.run(['$injector', function ($injector: IInjectorService) {
  // Inject $previousState so it initializes and registers hooks
  $injector.get('$previousState');
}]);

christopherthielen avatar Sep 22 '17 20:09 christopherthielen

Thanks a lot for that Chris, very much appreciated!

dmeagor avatar Oct 04 '17 14:10 dmeagor

Worked great, just had one issue, $transition$.params() gets the 'to' params rather than 'from'. Thanks!

lukebooroo avatar Oct 04 '17 15:10 lukebooroo

just had one issue

Good catch! Updated the code

christopherthielen avatar Oct 04 '17 19:10 christopherthielen

@christopherthielen - Since I don't have typescript in my project, is there anyway we can get this on NPM use this similarly to the plugins you have developed for sticky states, etc? Sticky states seems to be hairy without know the previous state.

logan-jobzmall avatar Feb 22 '18 00:02 logan-jobzmall

@christopherthielen - I am using angular 1.6.9 ui-router:1.0.15. Could you kindly suggest me how to use Previous state without using ui-router-extras. Thank you in advance

divyasreekandalam25 avatar Mar 26 '18 05:03 divyasreekandalam25

@logan-jobzmall I'm not interested in maintaining the previous state implementation, because I don't think it's very useful. I've transpiled it for you to javascript. If you want to publish this to NPM yourself, feel free!

https://gist.github.com/christopherthielen/babf6deebcd9a183dfecd37a03f75199

christopherthielen avatar Mar 26 '18 23:03 christopherthielen