0

I'm working on a Web-App with Angular 1.6 / MVC 4.6 / E.F 6.0. I've also added UI-Grid. It's working well. I'm trying to create a custom filter, like this part of documentation. My objective is to create the same custom filter than "Age". It's working on local, but not when I publish the WebApp. I have this two errors :

Possibly unhandled rejection: canceled
Error: [$injector:unpr] http://errors.angularjs.org/1.6.2/$injector/unpr?p0=nProvider%20%3C-%20n%20%3C-%20myCustomModalCtrl

I'm pretty sure that it's related to controller / directive that I've added for this custom filter. I have readed Angular JS help page, but I don't know How I could correct this error, and Why it's working only localy

JS

var PrintersApp = angular.module('PrintersApp', ['ui.grid', 'ui.grid.pagination', 'ui.grid.selection', 'ui.grid.exporter', 'ui.grid.moveColumns', 'ui.grid.autoResize']);

var Now = new Date();

PrintersApp.controller('PrintersController', ['$scope', '$http', '$filter', 'uiGridConstants',
    function ($scope, $http, $filter, uiGridConstants) {
        var store = $scope;
        $scope.highlightFilteredHeader = function (row, rowRenderIndex, col, colRenderIndex) {
            if (col.filters[0].term) {
                return 'header-filtered';
            } else {
                return '';
            }
        };
        var ExportDate = $filter('date')(Now, "MM-dd-yyyy");
        $scope.gridOptions = {
            enableFiltering: true,
            paginationPageSizes: [25, 50, 75],
            paginationPageSize: 25,
            enableGridMenu: true,
            enableSelectAll: false,
            exporterMenuPdf: false,
            exporterCsvFilename: ExportDate + '-PrintersDataExport.csv',
            exporterCsvLinkElement: angular.element(document.querySelectorAll(".custom-csv-link-location")),
            onRegisterApi: function (gridApi) {
                $scope.gridApi = gridApi;
            },
            onRegisterApi: function (gridApi) {
                $scope.gridApi = gridApi;
            },
            columnDefs: [
              { field: 'Date', enableFiltering: false, enableColumnMenu: false, enableSorting: false, width: 160 },
              { field: 'User', headerCellClass: $scope.highlightFilteredHeader, enableHiding: false, width: 160 },
              { field: 'Pc', headerCellClass: $scope.highlightFilteredHeader, enableHiding: false, width: 120 },
              { field: 'PrinterSrv', enableFiltering: $scope.highlightFilteredHeader, enableHiding: false, },
              {
                  field: 'PrinterName',
                  filterHeaderTemplate: '<div class="ui-grid-filter-container" ng-repeat="colFilter in col.filters"><div my-custom-modal></div></div>',
                  width: 320,
              },
              {
                  field: 'Default', filter: {
                      type: uiGridConstants.filter.SELECT,
                      selectOptions: [{ value: 'true', label: 'true' }, { value: 'false', label: 'false' }, ]
                  },
                  headerCellClass: $scope.highlightFilteredHeader, enableColumnMenu: false, enableSorting: false, width: 150
              },
            ]
        };

        $http.get('/AuditPrinters/GetAuditPrintersData')
        .then(function (response) {
            var datatest = response.data;
            datatest.forEach(function addDates(row, index) {
                TimeStamp = (row.Date).replace('/Date(', '').replace(')/', '')
                row.Date = $filter('date')(TimeStamp, "MM/dd/yyyy HH:mm:ss");
            });
            $scope.gridOptions.data = datatest;
        }, function (err) {
            alert("Erreur" + rr);
        });
        $scope.toggleFiltering = function () {
            $scope.gridOptions.enableFiltering = !$scope.gridOptions.enableFiltering;
            $scope.gridApi.core.notifyDataChange(uiGridConstants.dataChange.COLUMN);
        };
    }])

PrintersApp.directive('myCustomDropdown', function () {
  return {
    template: '<select class="form-control" ng-model="colFilter.term" ng-options="option.id as option.value for option in colFilter.options"></select>'
  };
})

PrintersApp.controller('myCustomModalCtrl', function ($scope, $compile, $timeout) {
  var $elm;
  $scope.showPrintersNameModal = function() {
    $scope.listOfPrinters = [];

    $scope.col.grid.appScope.gridOptions.data.forEach( function ( row ) {
        if ($scope.listOfPrinters.indexOf(row.PrinterName) === -1) {
            $scope.listOfPrinters.push(row.PrinterName);
      }
    });
    $scope.listOfPrinters.sort();
    $scope.gridOptions = { 
      data: [],
      enableColumnMenus: false,
      onRegisterApi: function( gridApi) {
        $scope.gridApi = gridApi;

        if ( $scope.colFilter && $scope.colFilter.listTerm ){
          $timeout(function() {
              $scope.colFilter.listTerm.forEach(function (PrinterName) {
              var entities = $scope.gridOptions.data.filter( function( row ) {
                  return row.PrinterName === PrinterName;
              }); 

              if( entities.length > 0 ) {
                $scope.gridApi.selection.selectRow(entities[0]);
              }
            });
          });
        }
      } 
    };

    $scope.listOfPrinters.forEach(function (PrinterName) {
        $scope.gridOptions.data.push({ PrinterName: PrinterName });
    });
    var html = '<div class="modal" ng-style="{display: \'block\'}"><div class="modal-dialog"><div class="modal-content"><div class="modal-header">Filter Ages</div><div class="modal-body"><div id="grid1" ui-grid="gridOptions" ui-grid-selection class="modalGrid"></div></div><div class="modal-footer"><button id="buttonClose" class="btn btn-primary" ng-click="close()">Filter</button></div></div></div></div>';
    $elm = angular.element(html);
    angular.element(document.body).prepend($elm);
    $compile($elm)($scope);
  };

  $scope.close = function() {
    var printersname = $scope.gridApi.selection.getSelectedRows();
    $scope.colFilter.listTerm = [];
    printersname.forEach(function (PrinterName) {
        $scope.colFilter.listTerm.push(PrinterName.PrinterName);
    });

    $scope.colFilter.term = $scope.colFilter.listTerm.join(', ');
    $scope.colFilter.condition = new RegExp($scope.colFilter.listTerm.join('|'));

    if ($elm) {
      $elm.remove();
    }
  };
})

PrintersApp.directive('myCustomModal', function () {
  return {
      template: '<label>{{colFilter.term}}</label><button ng-click="showPrintersNameModal()">...</button>',
    controller: 'myCustomModalCtrl',
  };
});
Guilherme Fidelis
  • 1,022
  • 11
  • 20
mrplume
  • 183
  • 1
  • 3
  • 18
  • Possible duplicate of ["Uncaught Error: \[$injector:unpr\]" with angular after deployment](http://stackoverflow.com/questions/19671962/uncaught-error-injectorunpr-with-angular-after-deployment) – mxr7350 Apr 12 '17 at 12:58
  • Thank you, yes it's very close, but Leonardo response was more clear for me – mrplume Apr 12 '17 at 13:20

1 Answers1

2

Not sure if this helps, but your issue might be related with the declaration of the myCustomModalCtrl controller. This declaration, compared with the other ones is missing the full qualified declaration for the injected services:

PrintersApp.controller('myCustomModalCtrl', function ($scope, $compile, $timeout) { [..] });

Should be:

PrintersApp.controller('myCustomModalCtrl', ['$scope', '$compile', 
'$timeout', function ($scope, $compile, $timeout) { [..] }]);

When your code is minified, the parameter $scope will be renamed to, for example, a instead. Which will cause the error you've received, since there's no service named a declared in the $injector.

In order to avoid this issue, we must tell the $injector the correct service name to inject for each parameter we request in our controller.

Take a look at this article for more information.

Leonardo Chaia
  • 2,755
  • 1
  • 17
  • 23