I'm having a problem trying to inject $ http to the factory. I miss the following error in Angular 1.6:
Circular dependency found: $rootScope <- $http <- $exceptionHandler <- $rootScope <- $route
And this was what I was doing so far:
var app = angular.module("app", []);
app
.controller("ctrl", function($scope) {
// controller
})
.factory('$exceptionHandler', ['$log', '$http', function($log, $http) {
return function myExceptionHandler(exception, cause) {
$log.warn(exception, cause);
// I show only this and it already throws error
console.log($http);
}
}]);
To work around the circular dependency, try the following.
Instead of injecting $http directly into the interceptor try injecting the $injector and use that directly to get $http.
var app = angular.module("app", []);
app.factory('$exceptionHandler', ['$log', '$injector', function($log, $injector) {
return function myExceptionHandler(exception, cause) {
var $http = $injector.get('$http');
$log.warn(exception, cause);
// I show only this and it already throws error
console.log($http);
}
}]);
Related
I am getting the infamous unknown provider error, and looked into every potential answer up here but I think that I am missing something:
app.js
var myApp = angular.module('myApp', [
'ngResource',
'myAppControllers',
'myAppServices',
'myAppFilters'
]).config([
'$locationProvider',
function(
$locationProvider) {
$locationProvider.html5Mode({
enabled: true,
requireBase: false,
rewriteLinks: false
});
}]);
var myAppControllers = angular.module('myAppControllers', []);
var myAppServices = angular.module('myAppServices', []);
var myAppFilters = angular.module('myAppFilters', []);
Item.js
myAppServices.factory('Item',
function($resource) {
return $resource('/api/items/:id');
});
ItemService.js (1)
myAppServices.factory('itemService',
function($q,
$http,
Item) {
return {
delete: function(id){
// Item, $q and $http are undefined here
return Item.delete({id: id}).$promise;
}
};
});
alternative ItemService.js (2)
myAppServices.factory('itemService', [
'$q',
'$http',
'Item', // If I don't inject it here I can use this service with $q and $http
function($q,
$http,
Item) {
return {
delete: function(id){
return Item.delete(id).$promise;
}
};
}]);
And in my controller:
myAppControllers.controller('ItemsCtrl', [
'$scope',
'itemService',
function(
$scope,
itemService) {
var ctrl = this;
ctrl.ItemService = ItemService;
ctrl.deleteItem = function(id){
ctrl.itemService.delete(id)
.then(function(response){
console.log(response);
}, function (error) {
console.log(error);
});
};
}]);
So if I try like in (1), I am getting undefined.delete is not a function in itemService.
If I try as in (2), the app fails to load with:
Unknown provider: ItemProvider <- Item <- itemService
So what am I doing wrong?
You have multiple issues here.
You need to have myAppServices as a dependency of myAppControllers in order to use it in a controller.
So, following should be how you do it:
var myAppServices = angular.module('myAppServices', []);
var myAppControllers = angular.module('myAppControllers', ['myAppServices']);
In myAppServices module you have Item service which uses $resource but you haven't injected ngResource as a dependency of myAppServices.
Here's your code in plunker without errors
EDIT: Also make sure all your files are included in index.html properly!
i think in $resource ur are missing argument it should look like
$resource('/api/items/:id', {id:'#id'});
Try (1) again , undefined is because of this
and also ur delete should be look like this
return Item.delete({id : id}).$promise;
routes.js
angular
.module('main')
.config(config);
config.$inject = ['$routeProvider', '$httpProvider'];
function config($routeProvider){
$routeProvider
.when('/', {
templateUrl:'main/views/landing.client.view.html',
controller:'MainController',
controllerAs:'mainCtrl',
resolve: {
orgTypes: orgTypes
}
})
.otherwise({
redirectTo:'/'
});
}
function orgTypes($http){
return $http
.get('emrsvs/orgTypes')
.then(function successCallBack(response){
return response;
}, function errorCallBack(error){
console.log(error);
});
}
controller.js
angular
.module('main')
.controller('MainController', MainController);
MainController.$inject = ['$rootScope', '$timeout', 'orgTypes'];
function MainController($rootScope, $timeout, orgTypes){
var mainCtrl = this;
mainCtrl.orgTypes = orgTypes;
}
Error
[$injector:unpr] Unknown provider: orgTypesProvider <- orgTypes <- MainController
Here i am injecting a dependency 'orgTypes' from route to controller. It produced unknown provider error. Is there anything wrong with my sysntax? can someone find my mistake
you should include following code in routes.js , before orgTypes function definition
angular.module('main')
.factory('orgTypes', orgTypes);
orgTypes.$inject = ['$http'];
/*You need to apply following changes also in controller*/
angular
.module('main')
.controller('MainController', MainController);
MainController.$inject = ['$rootScope', '$timeout', 'orgTypes'];
function MainController($rootScope, $timeout, orgTypes){
var mainCtrl = this;
orgTypes.then(function(response){
mainCtrl.orgTypes = response;
})
}
I can't see anything wrong if you inject the controller with the ng-view directive.
<div ng-app="main">
<ng-view></ng-view>
</div>
Your code works in this JSFiddle.
In your router config, you inject orgTypes from a resolver function. The $routeProvider service injects resolvers as locals into controllers. That method works OK.
If you use the ng-controller directive to load MainController, you will get that error. The $compile service doesn't have access to those resolvers in that case.
I'm trying to ensure that upon loading the frame state, that my $rootScope has all the necessary properties defined from previous states.
The ionic.utils module is properly injected into my angular app. This module comes from my services.js file.
angular.module('ionic.utils', [])
.factory('dataService', ['$rootScope','$q','$timeout', function($rootScope, $q, $timeout) {
return {
get: function() {
var deferred = $q.defer();
$timeout(function() {
deferred.resolve($rootScope);
}, 2000);
return deferred.promise;
}
}
}]);
Inside my controllers.js file, this is the corresponding controller for my frame state:
.controller('FrameCtrl', ['$scope','$state','$rootScope','dataService',
function($scope, $state, $rootScope, dataService) {
// get active address and delivery time.
dataService.get().success(function() {
console.log("derp");
});
}])
However, this controller returns the following console error upon state transition:
ionic.bundle.js:17696 TypeError: Cannot read property 'get' of undefined
at new <anonymous> (controllers.js:201)
at invoke (ionic.bundle.js:11591)
at Object.instantiate (ionic.bundle.js:11602)
at $get (ionic.bundle.js:14906)
at updateView (ionic.bundle.js:42986)
at IonicModule.directive.directive.compile.eventHook (ionic.bundle.js:42933)
at Scope.$get.Scope.$broadcast (ionic.bundle.js:20605)
at $state.transitionTo.$state.transition.resolved.then.$state.transition (ionic.bundle.js:34122)
at deferred.promise.then.wrappedCallback (ionic.bundle.js:19197)
at ionic.bundle.js:19283
I'm having trouble finding the error in the service I've written. Some help would be greatly appreciated!
EDIT
After adding the dependency injections into my controller, now the error has changed. Here it is:
TypeError: object is not a function
at new <anonymous> (controllers.js:202)
at invoke (ionic.bundle.js:11591)
at Object.instantiate (ionic.bundle.js:11602)
at $get (ionic.bundle.js:14906)
at updateView (ionic.bundle.js:42986)
at IonicModule.directive.directive.compile.eventHook (ionic.bundle.js:42933)
at Scope.$get.Scope.$broadcast (ionic.bundle.js:20605)
at $state.transitionTo.$state.transition.resolved.then.$state.transition (ionic.bundle.js:34122)
at deferred.promise.then.wrappedCallback (ionic.bundle.js:19197)
at ionic.bundle.js:19283
Your dependency array in controller is missing numerous dependencies passed to arguments
.controller('FrameCtrl', [ 'Rootscope', function($scope, $state,
$rootScope, Rootscope) {
Should be
.controller('FrameCtrl', ['$scope','$state', '$rootScope', 'Rootscope', function($scope, $state,
$rootScope, Rootscope) {
Sure seems confusing to me to name a service Rootscope!
Normally with promises we just use .then, which takes the success function as the first parameter and the error function as the second.
success and error are functions on a promise that AngularJS adds
for us when using $http or $resource. They're not standard, you
won't find them on other promises.
Code
dataService.get().then(function() {
console.log("derp");
});
Return was missing from deferred.resolve()
angular.module('ionic.utils', []).factory('dataService', ['$rootScope', '$q', '$timeout', function($rootScope, $q, $timeout) {
return {
get: function() {
var deferred = $q.defer();
$timeout(function() {
return deferred.resolve($rootScope);
}, 2000);
return deferred.promise;
}
}
}]);
Hopefully this will help you. Thanks.
I'm injecting controller from external file and I want to do the same thing for the service from external file. It should be registered in factory statement.
Injecting of the controller working
controllers
'use strict';
define(['angular', 'services'], function (angular) {
return angular.module('vcApp.controllers', ['vcApp.services'])
.controller('AuthCtrl', ['$scope', '$injector','AuthService', function($scope, $injector, AuthService) {
require(['auth/authCtrl'], function(authCtrl) {
$injector.invoke(authCtrl, this, {'$scope': $scope, 'AuthService':AuthService});
});
}]);
});
authCtrl
define([], function() {
return ['$scope', '$routeParams', '$location', '$http', 'AuthService', function($scope, $routeParams, $location, $http, authService) {
$scope.signIn = function() {
...
}
$scope.$apply();
}];
});
And now I want to inject service
services
'use strict';
define(['angular'], function (angular) {
angular.module('vcApp.services', [])
.factory('AuthService', ['$http', '$injector', function($http, $injector) {
require(['auth/authService'], function(authService) {
$injector.invoke(authService, this, {'$http': $http});
});
}]);
});
authService
define([], function() {
return ['$http', function ($http) {
return {
login: login
};
function login(username, password) {
var request = $http(...);
return(request);
}
}]
});
When authController calls authService.login(...), it throws error Error: [$injector:undef] Provider 'AuthService' must return a value from $get factory method..
This code was inspired by angular-requirejs-seed project.
As it says, Angular's factory() is expected to return the service object. You may have luck with something like:
define(['angular'], function (angular) {
angular.module('vcApp.services', [])
.factory('AuthService', ['$http', '$injector', function($http, $injector) {
var stub = {};
require(['auth/authService'], function(authService) {
angular.extend(stub, $injector.invoke(authService, this, {'$http': $http}));
});
return stub;
}]);
});
Here you define a stub for the service and extend it, when the service is actually lazy-loaded.
(By the way I think the last 2 arguments of $injector.invoke() are redundant in this case.)
If you want another idea about mixing RequireJS and Angular, that plays well with lazy loading and the r.js optimizer, you may take a look at angular-require-lazy.
I'm learning Angularjs and i'm trying to create a service to do common tasks that need to be done for all my controllers.
I'm currently getting the error:
TypeError: Cannot call method 'getAuthHeader' of undefined
app.js
var token = "mytoken"
var baseUrl = "mybaseUrl";
var myezteam = angular.module('myezteam', ['ui.bootstrap']);
myapp.config(function($routeProvider) {
$routeProvider
.when('/profile',
{
controller: 'ProfileController',
templateUrl: 'template.html'
})
.otherwise({redirectTo: '/profile'});
});
// This gets the basic information that is needed for every page
myapp.service('base', function() {
this.getAuthHeader = function($http) {
// Set authorization token so we know the user has logged in.
return $http.defaults.headers.common.Authorization = 'Bearer ' + token;
}
});
profile.js
myapp.controller('ProfileController', ['$scope', '$http', function($scope, $http, base) {
base.getAuthHeader($http); // <-- THIS LINE IS THROWING THE ERROR
}]);
Why is the error occurring and how can I fix it? Also, is there a way to setup a config on my app so that I don't need to call base.getAuthHeader($http); in every controller, but it will automatically get called when every controller is loaded?
You're not injecting your service base into your controller. You need to inject it in the same way you did with $scope and $http
myapp.controller('ProfileController', ['$scope', '$http', 'base',
function($scope, $http, base) { ... });