'unknown provider error' in Angular app

[亡魂溺海] 提交于 2019-12-08 05:15:54

问题


I followed the Angular docs to create my Service and saw an error message

http://docs.angularjs.org/error/$injector:unpr?p0=$scopeProvider%20%3C-%20$scope%20%3C-%20$users

This is my code:

var angularApp = angular.module("myApp", []);
angularApp.run(function($http) {
  $http.defaults.headers.common['Content-Type'] = 'application/x-www-form-urlencoded';
  $http.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
});

angularApp.service('$users', function($scope, $http, $cookie, $window) {
  // need to instantiate the service
  var newUsersServiceInstance;

  // upper case is resource
  var User = $resource('/user/:userId', {userId:'@id'});
  var MyPassword = $resource('/mypasswords/new');
  // lower case is instance you tend to want the instance
  // to be binded to the controller's scope
  $scope.user // = User.get({userId:123});

  $scope.getUser = function(id, s) {
    $scope.user = User.get({"userId": id}, s, e);
  }

  $scope.changePassword = function(data, s, e) {
    MyPassword.post(data, s, e);
  }

  // need to return the instance
  return newUsersServiceInstance;

});

angularApp.controller('passwordController', ['$scope', '$users', function($scope, $users) {

  $scope.changePasswordForm = function() {
    $users.changePassword(
      $.param($scope.data),
      function(data, xhr) {
          console.log(data);
      },
      function(data, xhr) {
          console.log(data);
          // error callback
          $scope.errors = data.errors;
      })
  }
  $scope.debug = function () {
   console.log($scope);
  }
}]);

I am not sure where I have gone wrong.

My new code after taking into account everybody's answer. Same error.

var angularApp = angular.module("myApp", []);
angularApp.run(function($http) {
  $http.defaults.headers.common['Content-Type'] = 'application/x-www-form-urlencoded';
  $http.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
});

angularApp.service('$users', function($http, $cookie, $window) {
  // upper case is resource
  var User = $resource('/user/:userId', {userId:'@id'});
  var MyPassword = $resource('/mypasswords/new');
  // lower case is instance you tend to want the instance
  // to be binded to the controller's scope
  this.user // = User.get({userId:123});

  this.getUser = function(id, s) {
    this.user = User.get({"userId": id}, s, e);
  }

  this.changePassword = function(data, s, e) {
    MyPassword.post(data, s, e);
  }

 return this;

});

angularApp.controller('passwordController', ['$scope', '$users', function($scope, $users) {

  $scope.changePasswordForm = function() {
    $users.changePassword(
      $.param($scope.data),
      function(data, xhr) {
          console.log(data);
      },
      function(data, xhr) {
          console.log(data);
          // error callback
          $scope.errors = data.errors;
      })
  }
  $scope.debug = function () {
   console.log($scope);
  }
}]);

Even after changing to use factory I see the same errors.

var angularApp = angular.module("myApp", []);
angularApp.run(function($http) {
  $http.defaults.headers.common['Content-Type'] = 'application/x-www-form-urlencoded';
  $http.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
});

angularApp.factory('$users', function($resource, $http, $cookie, $window) {
  // need to instantiate the service
  var newUsersServiceInstance = {};

  // upper case is resource
  var User = $resource('/user/:userId', {userId:'@id'});
  var MyPassword = $resource('/mypasswords/new');
  // lower case is instance you tend to want the instance
  // to be binded to the controller's scope
  newUsersServiceInstance.user // = User.get({userId:123});

  newUsersServiceInstance.getUser = function(id, s) {
    newUsersServiceInstance.user = User.get({"userId": id}, s, e);
  }

  newUsersServiceInstance.changePassword = function(data, s, e) {
    MyPassword.post(data, s, e);
  }

  // need to return the instance
  return newUsersServiceInstance;

});

angularApp.controller('passwordController', ['$scope', '$users', function($scope, $users) {

  $scope.changePasswordForm = function() {
    $users.changePassword(
      $.param($scope.data),
      function(data, xhr) {
          console.log(data);
      },
      function(data, xhr) {
          console.log(data);
          // error callback
          $scope.errors = data.errors;
      })
  }
  $scope.debug = function () {
   console.log($scope);
  }
}]);

回答1:


When you use .service, the function you pass in is invoked as a constructor function. You should not return an instance, try something like this:

angularApp.service('$users', function() {

  this.field1 = "something";

  this.method1 = function(){
  }
  //more fields

});

You return an instance only when you use .factory method. I don't see the point why you need to inject $scope into service function because service is designed to be a reusable component. In your case, you should get rid of $scope. Refactor the code like this:

angularApp.factory('$users', function($resource, $http, $cookie, $window) {//Declare $resource dependency
  // need to instantiate the service
  var newUsersServiceInstance;

  // upper case is resource
  var User = $resource('/user/:userId', {userId:'@id'});
  var MyPassword = $resource('/mypasswords/new');
  // lower case is instance you tend to want the instance
  // to be binded to the controller's scope
  newUsersServiceInstance.user; // = User.get({userId:123});

  newUsersServiceInstance.getUser = function(id, s) {
    newUsersServiceInstance.user = User.get({"userId": id}, s, e);
  }

  newUsersServiceInstance.changePassword = function(data, s, e) {
    MyPassword.post(data, s, e);
  }

  // need to return the instance
  return newUsersServiceInstance;

});

You also have to declare dependency with ngResource, ngCookies if you need to inject them into your factory function.

var angularApp = angular.module("myApp", ['ngResource','ngCookies']);

And don't forget to add:

 <script src="angular-resource.js"></script>
 <script src="angular-cookies.js"></script>

If you use a CDN, you could add:

    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular-resource.js">       </script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.7/angular-cookies.js">       </script>



回答2:


There are two ways to write service.

A) use .factory

B) use .service

If the service uses $resource, then inside the module, you need to require ngResource, download and add the angular-resource.js accordingly.

To use ngResource,

var angularApp = angular.module("myApp", ['ngResource']);

for A)

angularApp.factory('$users', function($resource, $http) {
  // need to instantiate the service
  var newUsersServiceInstance = {};

  // upper case is resource
  var User = $resource('/user/:userId', {userId:'@id'});
  var MyPassword = $resource('/mypasswords/new');
  // lower case is instance you tend to want the instance
  // to be binded to the controller's scope
  newUsersServiceInstance.user // = User.get({userId:123});

  newUsersServiceInstance.getUser = function(id, s) {
    newUsersServiceInstance.user = User.get({"userId": id}, s, e);
  }

  newUsersServiceInstance.changePassword = function(data, s, e) {
    MyPassword.post(data, s, e);
  }

  // need to return the instance
  return newUsersServiceInstance;

});

for B)

angularApp.service('$users', function($resource, $http) {

  // upper case is resource
  var User = $resource('/user/:userId', {userId:'@id'});
  var MyPassword = $resource('/mypasswords/new');
  // lower case is instance you tend to want the instance
  // to be binded to the controller's scope
  this.user // = User.get({userId:123});

  this.getUser = function(id, s) {
    this.user = User.get({"userId": id}, s, e);
  }

  this.changePassword = function(data, s, e) {
    MyPassword.post(data, s, e);
  }

});

I chose B. Less lines to write.




回答3:


Services don't have $scope, you can access $rootScope if needed but it looks like you just want to return an object with all of the functions you want to use.

angularApp.factory('$users', function($http, $cookie, $window) {
  // need to instantiate the service
  var newUsersServiceInstance = {};

  // upper case is resource
  var User = $resource('/user/:userId', {userId:'@id'});
  var MyPassword = $resource('/mypasswords/new');
  // lower case is instance you tend to want the instance
  // to be binded to the controller's scope
  newUsersServiceInstance.user // = User.get({userId:123});

  newUsersServiceInstance.getUser = function(id, s) {
    newUsersServiceInstance.user = User.get({"userId": id}, s, e);
  }

  newUsersServiceInstance.changePassword = function(data, s, e) {
    MyPassword.post(data, s, e);
  }

  // need to return the instance
  return newUsersServiceInstance;

});



回答4:


You might get rid of $scope It doesn't go there :P.

$scope is a value used in conjunction with controllers.

I'd recommend making your service something like:

angularApp.factory('$users', function($http) {
    var userService = {activeUser:{name:'anonymous'}};
    return angular.extend(userService,
        {
            getUser: function(id){
                return $http.get('/user/'+id).then(function(response){
                           userService.activeUser = response.data;
                           return userService.activeUser;
                       });
            },
            changePassword: function(data,se,e){
                return $http.post(...)
            }
        }
    );
});



回答5:


As states in Angular docs: $injector:unpr (Unknown Provider)

Attempting to inject a scope object into anything that's not a controller or a directive, for example a service, will throw an Unknown provider: $scopeProvider <- $scope error. This might happen if one mistakenly registers a controller as a service

angular.module('myModule', [])
.service('MyController', ['$scope', function($scope) {
  // This controller throws an unknown provider error because
  // a scope object cannot be injected into a service.
}]);


来源:https://stackoverflow.com/questions/21212444/unknown-provider-error-in-angular-app

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!