Question:
How can I use $mdToast
inside an interceptor without triggering the error?
Setup:
Interceptor definition:
(function () {
'use strict';
angular
.module('appponents.http-errors-interceptors')
.factory('HttpError500Interceptor', HttpError500Interceptor);
/* @ngInject */
function HttpError500Interceptor($q,
$mdToast,
$filter) {
var interceptor = {};
interceptor.responseError = responseError;
function responseError(responseError) {
if (responseError.status === 500) {
$mdToast.show($mdToast.simple()
.content($filter('translate')('APP.COMPONENTS.HTTP_ERRORS_INTERCEPTORS.500'))
.position('bottom right')
.hideDelay(5000));
}
return $q.reject(responseError);
}
return interceptor;
}
})();
Interceptor config:
(function () {
'use strict';
angular
.module('appponents.http-errors-interceptors')
.config(moduleConfig);
/* @ngInject */
function moduleConfig($httpProvider) {
$httpProvider.interceptors.push('HttpError500Interceptor');
}
})();
Issue:
When I load the application it triggers the following error:
Uncaught Error: [$injector:cdep] Circular dependency found: $http <- $templateRequest <- $$animateQueue <- $animate <- $$interimElement <- $mdToast <- HttpError500Interceptor <- $http <- $templateFactory <- $view <- $state
Question:
How can I use $mdToast
inside an interceptor without triggering the error?
Setup:
Interceptor definition:
(function () {
'use strict';
angular
.module('app.ponents.http-errors-interceptors')
.factory('HttpError500Interceptor', HttpError500Interceptor);
/* @ngInject */
function HttpError500Interceptor($q,
$mdToast,
$filter) {
var interceptor = {};
interceptor.responseError = responseError;
function responseError(responseError) {
if (responseError.status === 500) {
$mdToast.show($mdToast.simple()
.content($filter('translate')('APP.COMPONENTS.HTTP_ERRORS_INTERCEPTORS.500'))
.position('bottom right')
.hideDelay(5000));
}
return $q.reject(responseError);
}
return interceptor;
}
})();
Interceptor config:
(function () {
'use strict';
angular
.module('app.ponents.http-errors-interceptors')
.config(moduleConfig);
/* @ngInject */
function moduleConfig($httpProvider) {
$httpProvider.interceptors.push('HttpError500Interceptor');
}
})();
Issue:
When I load the application it triggers the following error:
Share Improve this question edited Feb 18, 2018 at 7:43 Splaktar 5,9045 gold badges45 silver badges75 bronze badges asked Jan 31, 2016 at 20:43 DiosneyDiosney 10.6k15 gold badges68 silver badges113 bronze badges 2Uncaught Error: [$injector:cdep] Circular dependency found: $http <- $templateRequest <- $$animateQueue <- $animate <- $$interimElement <- $mdToast <- HttpError500Interceptor <- $http <- $templateFactory <- $view <- $state
- didi you find the fix? – Kumar Sambhav Commented Sep 20, 2016 at 4:35
- @KumarSambhav Yes, I was able to workaround this, see my answer below to fit your specific use-case. – Diosney Commented Sep 20, 2016 at 13:40
3 Answers
Reset to default 5One work around that has helped me in the past is to use $injector
to get your dependency at runtime instead of at configuration time. So, something like:
/* @ngInject */
function HttpError500Interceptor($q,
$injector,
$filter) {
function responseError(responseError) {
var $mdToast = $injector.get('$mdToast');
When your cyclic dependency does not cause problems, which it probably doesn't in this case, this will do the trick.
Neither of the provided solutions worked for me, so I'm posting here what I did so anyone with the same issue can have a range of workarounds to use.
What I really wanted was to have a mon ponent to handle HTTP interceptors named interceptors
and show the messages directly from the module, and happily, since the final solution is more elegant, it triggered this error while injecting the $mdToast
service.
The solution I came later, which I already said, is more elegant that my first fix to the issue is:
- to have a mon ponent to handle HTTP interceptors named
interceptors
, - to have a mon ponent to handle global notifications named
notifications-hub
.
Then, in the interceptors
module, I trigger a global event with:
$rootScope.$broadcast('notifications:httpError', responseError);
Then, in the notifications-hub
module, I registered on the event and used the $mdToast
, which was injected without errors in the notifications service:
$rootScope.$on('notifications:httpError', function (event, responseError) {
NotificationsHubService.processErrorsAndShowToast(responseError);
});
NotificationsHubService
is the service injecting $mdToast
.
Conclusion:
I used a global event as a glue between the low-level interceptors and the notifications subsystem to overe the issue.
Hopefully it will be of use for anyone else.
What you should do is create a function that brings you the toaster at run time
var getToaster = ()=>{
var toaster = $injector.get('$mdToaster');
return toaster;
}
Now call it only when you need it - this will provide a work around the dependency circular