Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS Filter with TypeScript and injection

Can somebody provide me with an example of how I can create an Angular Filter in TypeScript that uses dependency injection. At the bottom is what I currently have, which is working fine, but what I want to do is in is the function I want to have access to $filter, so that I can change the line return date.ToString() into $filter'date'. That way I use the built in date filter to show a nice friendly short date.

class FriendlyDateFilter {

    public static Factory() {
        return function (input): string {
            if (angular.isDate(input)) {
                var date: Date = input;
                var today = new Date();
                var days = Math.abs(getDaysBetweenDates(today, date));
                if (days < 7) {
                    var dayInWeek = date.getDay();
                    switch (dayInWeek) {
                        case 0:
                            return "Sunday";
                            break;
                        case 1:
                            return "Monday";
                            break;
                        case 2:
                            return "Tuesday";
                            break;
                        case 3:
                            return "Wednesday";
                            break;
                        case 4:
                            return "Thursday";
                            break;
                        case 5:
                            return "Friday";
                            break;
                        case 6:
                            return "Saturday";
                            break;
                    }
                } else {
                    return date.toString();
                }
            } else {
                return input;
            }
        }

        function getDaysBetweenDates(d0, d1) {
            var msPerDay = 8.64e7;

            // Copy dates so don't mess them up
            var x0: any = new Date(d0);
            var x1: any = new Date(d1);

            // Set to noon - avoid DST errors
            x0.setHours(12, 0, 0);
            x1.setHours(12, 0, 0);

            // Round to remove daylight saving errors
                return Math.round((x1 - x0) / msPerDay);
            }
        }

    }
}

angular.module("ReadingLog").filter("FriendlyDateFilter", FriendlyDateFilter.Factory);
like image 650
Paul Cavacas Avatar asked Jun 28 '15 15:06

Paul Cavacas


2 Answers

First, you need to use angular.d.ts definition file.

Then, you simply do the following :

MyFilter.$inject = ["$log"];
function MyFilter ($log: ng.ILogService): Function {
  return function(msg: string) {
    $log.log("I'm injected!");
    return msg;
  };
}
angular.module("testModule").filter("MyFilter", MyFilter);

$inject property is available in Function thanks to these lines in angular.d.ts:

// Support for painless dependency injection
interface Function {
  $inject?: string[];
}

See https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/angularjs/angular.d.ts#L12

like image 127
Fidan Hakaj Avatar answered Sep 18 '22 22:09

Fidan Hakaj


It's generally better to use a function+module instead of a class when writing an Angular filter. You can structure the code like this:

function FriendlyDateFilter($filter) {
    return function (s: string): string {
        /* Your logic here */
    }
    /* Helper logic here */
}
module FriendlyDateFilter {
    export var $inject = ['$filter'];
}

angular.module("ReadingLog").filter("FriendlyDateFilter", FriendlyDateFilter);

You could also place both FriendlyDateFilter declarations inside another module if you're trying to avoid adding too much to the global scope.

like image 37
Ryan Cavanaugh Avatar answered Sep 21 '22 22:09

Ryan Cavanaugh