I have the following Angular function:
$scope.updateStatus = function(user) {
$http({
url: user.update_path,
method: "POST",
data: {user_id: user.id, draft: true}
});
};
But whenever this function is called, I am getting ReferenceError: $http is not defined in my console. Can someone help me understanding what I am doing wrong here?
Probably you haven't injected $http service to your controller. There are several ways of doing that.
Please read this reference about DI. Then it gets very simple:
function MyController($scope, $http) {
// ... your code
}
I have gone through the same problem when I was using
myApp.controller('mainController', ['$scope', function($scope,) {
//$http was not working in this
}]);
I have changed the above code to given below. Remember to include $http(2 times) as given below.
myApp.controller('mainController', ['$scope','$http', function($scope,$http) {
//$http is working in this
}]);
and It has worked well.
Just to complete Amit Garg answer, there are several ways to inject dependencies in AngularJS.
You can also use $inject to add a dependency:
var MyController = function($scope, $http) {
// ...
}
MyController.$inject = ['$scope', '$http'];
Related
I'm a newbie in Angular, i whant to make use of $controllerProvider, i see an example like my code, but the attribute register got undefined:
var appTmw = angular.module('appTmw', ['ui.router']);
appTmw.config(function($stateProvider, $urlRouterProvider, $controllerProvider) {
appTmw.register = {
controller: $controllerProvider.register
};
})
and here, a register of controller, the register attribute got undefined:
appTmw.register.controller('CustomersController', ['$scope', 'config', 'dataService',
function ($scope, config, dataService) {
//Controller code goes here
}]);
what a problem with the code?
controllerProvider is the $controller service used by Angular to create new controllers:
https://docs.angularjs.org/api/ng/provider/$controllerProvider
If you are new to angular I suggest you to use the standard way to create a controller:
var appTmw = angular.module('appTmw', ['ui.router']);
appTmw.controller('controllerName', function($scope){
//your code for the controller here
});
I hope it helps.
I am trying to attach notes to $scope instead of controller(this) in the following code:
angular.module('NoteWrangler')
.controller('NotesIndexController', ['$http', function($http) {
var controller = this;
$http({method: 'GET', url: '/notes'}).success(function(data) {
controller.notes = data;
});
}]);
So, when I define $scope like the following :
.controller('NotesIndexController', ['$scope', function($scope)
It doesn't work as I would need to define $http somewhere in order to use it in the code? So, where exactly I should define $scope then?
I have referred this documentation.
You don't "define" $scope, it is a framework object that is managed for you.
If you use the ControllerAs Syntax, your controller can be added to $scope as a property. Otherwise, you would need to refer to the $scope object that is injectable through Angular Dependency Injection. You can inject as many dependencies as you need for your app.
So, the two options which you have available to you are:
ControllerAs:
angular.module('NoteWrangler')
.controller('NotesIndexController', ['$http', function($http) {
var controller = this;
$http({method: 'GET', url: '/notes'}).success(function(data) {
controller.notes = data;
});
}]);
<div ng-controller="NotesIndexController as controller">
{{controller.notes}}
</div>
Direct $scope:
angular.module('NoteWrangler')
.controller('NotesIndexController', ['$scope', '$http', function($scope, $http) {
var controller = this;
$http({method: 'GET', url: '/notes'}).success(function(data) {
$scope.notes = data;
});
}]);
<div ng-controller="NotesIndexController">
{{notes}}
</div>
Note that the $scope object is implicit in the first example and not required in the controller code, and explicit in the second. Also note, $scope has some specific rules regarding primitives and Prototype Inheritance, so it is always recommended to use a dot in your HTML bindings, which the ControllerAs syntax enforces automatically.
Ultimately, the choice of which syntax to use is up to you, but it's recommended to be consistent throughout your application, and either always reference $scope or only reference it for special properties you can't reach any other way.
angular
.module('NoteWrangler')
.controller('NotesIndexController', ['$scope', '$http', function($scope, $http) {
$http({method: 'GET', url: '/notes'}).success(function(data) {
$scope.notes = data;
});
}]);
Not sure why you are using var controller = this; but you have not injected $http
You can use it like
.controller('NotesIndexController', ['$scope', '$http', function($scope, $http){
$http({method: 'GET', url: '/notes'})
.success(function(data) {
$scope.notes = data;
});
}]);
I am trying to use Angular's routing to resolve the necessary objects for the controller scope. I have read a few tutorials on how to do this but I still get an Unknown Provider error. The issue seems to be with project being injected into ProjectDetailCtrl.
app.js
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config( function ($interpolateProvider, $routeProvider) {
$routeProvider
...
.when('/project/:projectId', {
templateUrl : 'partials/_project_detail.html',
controller: 'ProjectDetailCtrl',
resolve: {
project: function ($route, MyService) {
return MyService.get('projects/', $route.current.params.projectId).then(function(data) {
console.log('VERIFY DATA: ', data);
return data;
});
}
}
controllers.js
.controller('ProjectDetailCtrl', function ($scope, project) {
$scope.project = project;
}
Edit
services.js
.factory('MyService', function ($http, $q) {
var MyService = {
...
get: function (items_url, objId) {
var defer = $q.defer();
$http({method: 'GET',
url: api_url + items_url + objId}).
success(function (data, status, headers, config) {
defer.resolve(data);
}).error(function (data, status, headers, config) {
defer.reject(status);
});
return defer.promise;
},
Edit 2
The issue is apparently not with the Service method, as this also produces the error:
app.js
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config( function ($interpolateProvider, $routeProvider) {
$routeProvider
...
.when('/project/:projectId', {
templateUrl : 'partials/_project_detail.html',
controller: 'ProjectDetailCtrl',
resolve: {
project: {title: 'foo'}
}
});
})
I can verify my resolve function is being returned properly, but Angular still complains that project is unidentified. What is this issue here? I have tried making my controllers into a module and passing that to the myApp module, but I still get the same Unidentified Provider issue for project.
Note: I am using Angular 1.2.9.
Edit 3: solution
So the issue was this line in my template:
<!-- WRONG: <div ng-controller="ProjectDetailCtrl">-->
<div>
<h2 ng-show="project">Project: <strong>{{ project.title }}</strong></h2>
</div>
Apparently the ng-controller directive cannot be use with resolve.
You forgot to add ngRoute as a dependency for your module. Thats why $routeProvider and $route service are undefined.
Update:
See this example. Problem was in ng-controller directive
You're returning the MyService.get, which is a promise, and then within the result of the promise, you're returning the data.... but to what?
You want to return the promise, but not the original promise... so you create your own promise using $q, and Angular will wait and resolve it for you before loading your route.
project: function ($route, MyService) {
var deferred = $q.defer();
MyService.get('projects/', $route.current.params.projectId).then(function(data) {
console.log('VERIFY DATA: ', data);
deferred.resolve(data);
});
return deferred.promise;
}
Or, assuming MyService.get returns a promise, you should be able to just do
project: function ($route, MyService) {
return MyService.get('projects/', $route.current.params.projectId);
}
And obviously inject $q into config
This question has been asked before, therefore it's a possible duplicate.
The top answer points out usage of controllers within markup to have caused this.
Search your codebase (markup or templates to be exact) for the term ng-controller.
Verify if there is a matching controller, as in this case ProjectDetailCtrl
Remove it from the markup
It solved the problem in my case.
I asked a similar question earlier when attempting to inject $scope and $http into a controller Cannot call method 'jsonp' of undefined in Angular.js controller. Now I'm attempting to refactor that code slightly by moving the code into a function within the controller. I'm encountering similar issues and can't seem to grasp the mechanics of dependency injection in Angular. Below is my new code. Both $scope and $http are undefined. What I'm attempting to do is make an http request when didSelectLanguage() fires and assign the resulting data to the "image" variable in the $scope from the parent controller. Can someone enlighten me as to how dependency injection is supposed to work in this example?
angular.module('myApp.controllers', []).
controller('ImagesCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.didSelectLanguage=function($scope, $http) {
console.log($scope);
$http.jsonp('http://localhost:3000/image?quantity=1&language='+this.language+'&Flag=&callback=JSON_CALLBACK')
.success(function(data){
$scope.image = data;
});
}
}])
When you create your controller:
angular.module('myApp.controllers', []).
controller('ImagesCtrl', ['$scope', '$http', function ($scope, $http) {
// ...
}]);
The stuff inside the body of the controller function automatically has access to $scope and $http because of closures. Thus, there's no need to specify anything additional for a function on the $scope to have access to these things:
angular.module('myApp.controllers', []).
controller('ImagesCtrl', ['$scope', '$http', function ($scope, $http) {
$scope.didSelectLanguage = function() {
$http.jsonp('http://localhost:3000/image?quantity=1&language=' + this.language + '&Flag=&callback=JSON_CALLBACK');
.success(function(data) {
$scope.$parent.image = data;
});
}
}]);
When didSelectLanguage is run, it sees the references to $http, and reaches out of the function into the outer function to get the value of the reference; the same happens for $scope inside the success callback.
So, in short, there's no need to pass any arguments to your didSelectLanguage function, nor is there in this case any reason to use the $injector.
With the help of Michelle Tilley's comment & article I solved the problem as follows. However, I'm going to keep the question open until someone else answers or until I understand enough to write an accompanying explanation.
controller('ImagesCtrl', ['$scope', '$http', '$injector', function ($scope, $http, $injector) {
$scope.didSelectLanguage=function() {
$http.jsonp('http://localhost:3000/image?quantity=1&language='+this.language+'&Flag=&callback=JSON_CALLBACK')
.success(function(data){
$scope.$parent.image = data;
});
}
}])
I have written a service in AngularJS, but I can't get it to work with the angular-seed way of doing things.
The controller code is as follows:
/*function PhotoCtrl($scope, Photo) {
$scope.photos = Photo.query();
}*/
angular.module('myApp.controllers', []).
controller('PhotoCtrl', [function($scope,Photo) {
$scope.photos = Photo.query();
}])
.controller('MyCtrl2', [function() {
}]);
Note that the commented out section works fine, but I would like to handle it somewhat like the (recommended) second way.
The error I get is that Photo is undefined, so my guess would be my method of passing (injecting) it is wrong, but I can't find out how to do it correctly
You need to define the Photo service:
angular.module('myApp.controllers', [])
.service('Photo', ['$log', function ($log) {
return {
query: function() {
// the query code here.
}
};
}])
.controller('PhotoCtrl', ['$scope', 'Photo', function ($scope, Photo) {
$scope.photos = Photo.query();
}])
.controller('MyCtrl2', [function() {
}]);
A couple of references:
http://docs.angularjs.org/api/angular.Module
http://docs.angularjs.org/api/AUTO.$provide#service
In the above sample code I used parameters aliasing, which I suggest in order to avoid issues when minifying your code.
See also an example here:
AngularJS multiple uses of Controller and rootScope
And a Plunker here:
http://plnkr.co/edit/Bzjruq