0

I generated an AngularJS app with Yeoman AngularJS generator, which is working fine when running with original source code.

But when I try to run the app from the dist folder generated by Grunt build I get the following error:

vendor.972e9c35.js:5 Error: [$injector:unpr] Unknown provider: aProvider <- a https://errors.angularjs.org/1.7.2/$injector/unpr?p0=aProvider%20%3C-%20a at vendor.972e9c35.js:3 at vendor.972e9c35.js:4 at Object.d [as get] (vendor.972e9c35.js:4) at vendor.972e9c35.js:4 at d (vendor.972e9c35.js:4) at e (vendor.972e9c35.js:4) at Object.g [as invoke] (vendor.972e9c35.js:4) at l.instance (vendor.972e9c35.js:5) at vendor.972e9c35.js:26 at i (vendor.972e9c35.js:6) "Possibly unhandled rejection: {}"

I see that that's a common error, and that the solution should be declaring all the services inside an array(which you can do automaticcally with ng-annotated npm module) - which I did, but still I get the same error.

Here is my original .js file with all the controllers and services:

var routerApp = angular.module('routerApp', ['ui.router','ui.grid','ui.bootstrap']);


routerApp.controller('expensesListCtrl',["$http", "gridService", function ($http,gridService) {
    var vm = this;
    vm.recievedData = false;
    vm.searchInput;
    vm.gridOptions = gridService.getOption();
    //vm.gridOptions.columnDefs = [{field:"name"},{field:"amount"},{field:"type"},{field:"time",type:'date'}];

    $http.get("http://localhost:8080/expenses").then(function(response){

      gridService.setData(response.data.expenses);
      gridService.setUnfilteredData(response.data.expenses);
      vm.recievedData = true;
    }).catch(function (error) {
        console.log(error);
    });
}]);

routerApp.factory('gridService',function () {


  var gridServiceInstance = {};
  gridServiceInstance.gridOptions = {};
  gridServiceInstance.gridOptions.columnDefs = [{field:"name"},{field:"amount"},{field:"type"},{field:"time",type:'date'}];
  gridServiceInstance.unfilteredData;

  gridServiceInstance.getData = function () {
    return gridServiceInstance.gridOptions.data;
  }

  gridServiceInstance.setData = function (data) {
    gridServiceInstance.gridOptions.data = data;
  }

  gridServiceInstance.getOption = function(){
    return gridServiceInstance.gridOptions;
  }

  gridServiceInstance.setUnfilteredData = function (data) {
    gridServiceInstance.unfilteredData = data;
  }

  gridServiceInstance.getUnfilteredData = function(){
    return gridServiceInstance.unfilteredData;
  }

  return gridServiceInstance;

})

routerApp.controller('mainPageNavCtrl',["$scope", "$uibModal", "$http", "gridService", function ($scope,$uibModal,$http,gridService) {

    var vm = this;
    $scope.check = "check str";


    $scope.addPath = function(){
        console.log("add path");
        $uibModal.open({
            templateUrl: 'addPathModal.html',
            controller: ["$scope", "$uibModalInstance", function ($scope, $uibModalInstance) {

                $scope.addExpenseForm = {};

                $scope.ok = function () {
                    $http.post("http://localhost:8080/expenses",$scope.addExpenseForm).then(function(response){
                        console.log(response);
                    })
                    $uibModalInstance.close();
                };

                $scope.cancel = function () {
                    $uibModalInstance.dismiss('cancel');
                };
            }]
        })
    }
    $scope.searchText = function () {
      console.log("inside search text");

      if($scope.searchInputText == null || $scope.searchInputText.length == 0)
      {
        gridService.setData(gridService.getUnfilteredData());
        return;
      }

      var filteredData = gridService.getUnfilteredData().filter(function (element) {
        if ( (element.name.indexOf($scope.searchInputText) != -1) || element.type.indexOf($scope.searchInputText) != -1) {
          return true;
        }
        return false;
      });
      gridService.setData(filteredData);
    }

}])


routerApp.config(["$stateProvider", "$urlRouterProvider", function($stateProvider, $urlRouterProvider) {

    $urlRouterProvider.otherwise('/home');
    $stateProvider

    // HOME STATES AND NESTED VIEWS ========================================
        .state('home', {
            url: '/home',
            templateUrl: 'expensesList.html',
            controller: 'expensesListCtrl as vm'
        })

        // ABOUT PAGE AND MULTIPLE NAMED VIEWS =================================
        .state('about', {
            // we'll get to this in a bit
        });

}]);

What am I missing? Thanks for the help!!

nadavgam
  • 2,014
  • 5
  • 20
  • 48
  • 1
    Update factory code to routerApp.factory('gridService', [ function () { //factory code }]); Keep everything else same – Shantanu Aug 13 '18 at 18:47
  • @Shantanu Working Thanks!! can you refer me to the place the explain why that was the problem?!!! – nadavgam Aug 13 '18 at 19:25

1 Answers1

1

Angular infers the controller's dependencies from the names of arguments to the controller's constructor function, if you were to minify the JavaScript code for expensesListCtrl controller, all of its function arguments would be minified as well, and the dependency injector would not be able to identify services correctly. Same logic aplies for defining services & factories.

You can overcome this problem by annotating the function with the names of the dependencies, provided as strings, which will not get minified.

Angular invokes certain functions (like service factories and controllers) via the injector. You need to annotate these functions so that the injector knows what services to inject into the function. There are three ways of annotating your code with service name information:

  • Using the inline array annotation (preferred)
  • Using the $inject property annotation
  • Implicitly from the function parameter names (has caveats) So, you've used the 1st approach, you need to use it for factory also (even though there're no explicit dependencies needed).

So, following should fix the issue:

routerApp.factory('gridService', [ function () { /*factory code*/ }]);

Angularjs dependency annotation

declaring-angularjs-modules-for-minification

Shantanu
  • 3,483
  • 2
  • 17
  • 20