Filtering for Parameters

145 Views Asked by At

When using the $urlMatcherFactory provider to create new parameter types, is there a way to filter types while encoding/decoding or validating them? I need some "date" parameters, and it seems easiest to just create a custom type that can encode/decode them from the URL, as the built-in "date" type does not use the same date formats I want. I need to do this in a config block, as I need to do it before actually defining the states. This means I can only use providers (as far as I know, please correct me if I am wrong).

I found a way to use the date parser service from Angular Bootstrap for decoding the date, by injecting the uibDateParserProvider provider then retrieving the service with $get, but this does not seem like the best way to go. Also, it seems like the $filter provider does not work the same way, as $filterProvider.$get returns an array with an injection function or something like that as the 2nd element. This injection function is not the $filter service. I have not delved deeply enough into the angular source to be able to figure out what it actually is, but would be very interested to find out. I know I could parse the dates out myself, but why do that when there are so many helpful angular services to do it for me?

Here is an example of what I am trying to do (uses ES6):

angular.module('myModule').config(myStates);

function myStates($filterProvider, $urlMatcherFactoryProvider, $stateProvider, uibDateParserProvider) {
    const decodeDateFormat = 'yyyy-MM-dd'; // the decoder date format
    const encodeDateFormat = 'MMM dd, yyyy'; // the encoder format, which is different from the decoder format

    $urlMatcherFactoryProvider.type('mydate', {
        // encode when switching states, e.g. `$state.go()`
        encode: item => {
            const $filter = $filterProvider.$get(); // returns an array like: ['$filter', filterService] (not sure what the 2nd element is)
            $filter('date')(item, decodeDateFormat); // this is what I ultimately want to do
        },
        // decode from the URL so we can use it as a date
        // this uses a different format from the encoder date format
        decode: item => {
            const uibDateParser = uibDateParserProvider.$get(); // returns the uibDateParser service
            return uibDateParser.parse(item, encodeDateFormat);
        },
        // validate
        is: item => {
            return item == null || angular.isDate(item); // just need to know if it is a date
        },
    });

    $stateProvider.state('myState', {
        url: 'my-path?{someParam:mydate}',
        someParam: null,
    });
}

Is there any way to use services when creating parameter types for the Angular UI Router? Otherwise, how do I get the $filter service from its provider, so I can do the filtering?

1

There are 1 best solutions below

6
On

I'm able to use the $filter service by getting it from the $injectorProvider it self, e.g., $injectorProvider.$get().get('$filter');.

The following snippet is an example of usage in the config phase.

angular.module('myApp', [])
  .config(function($injectorProvider) {
    var $filter = $injectorProvider.$get().get('$filter');
    console.log($filter('date')(new Date(), 'yyyy-MM-dd'));
  });
angular.element(function() {
  angular.bootstrap(document, ['myApp']);
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.0/angular.js"></script>