Reputation: 7752
I'm trying to change some $rootscope variables from within a controller after a I have received a promise from a service.
The $rootscope variables are used to set the html page title attribute etc.
Below is the code I have, I created a function called changeRootPageNotFound()
to change the $rootscope variables. It does not work if it's called in the promise.then
function.
app.controller('mainController', ['$routeParams', '$scope', '$rootScope', 'mainService', function ($routeParams, $scope, $rootScope, mainService) {
var mainCtrl = this;
mainCtrl.id = $routeParams.itemId;
var promise = mainService.getData($routeParams.id);
promise.then(function (response)
{
if (response.data.data) {
mainCtrl.data = response.data.data;
} else {
mainCtrl.data = false;
changeRootPageNotFound();
}
});
function changeRootPageNotFound() {
$rootScope.title = "Page Not Found - 404";
$rootScope.titleSuffix = "";
}
// changeRootPageNotFound(); // works here
}]);
How can I change the $rootscope variables after I have received the deferred promise from the service?
Upvotes: 1
Views: 698
Reputation: 48968
Add a .catch
method:
promise.then(function (response)
{
//if (response.data.data) {
mainCtrl.data = response.data.data;
//} else {
// mainCtrl.data = false;
// changeRootPageNotFound();
//}
}).catch(function(errorResponse) {
console.log(errorResponse.status);
mainCtrl.data = false;
changeRootPageNotFound();
throw errorResponse;
});
The $http
service rejects the promise when the status is outside the range 200-299.
What is the
throw errorResponse;
for, can it be left out?
If the throw errorResponse
is omitted, the rejection handler returns a value of undefined
. This will convert the rejected promise to a fulfilled promise that resolves as undefined
. If there is no further chaining, it can be left out.
A common cause of problems is programmers being unaware of this and unintentionally converting promises.
instead of
.catch
you can pass the same function to then as the 2nd argument
One of the subtle differences between .catch
and using the 2nd argument of the .then
method, is that runtime errors in the .then
success handler will not be caught in the rejection handler of the 2nd argument.
Upvotes: 2
Reputation: 1034
According to your snippet your code should have worked. In my plunker its working after the deferred promise also.
// Code goes here
angular.module('Test',[])
.service('Service', function($q){
this.ts = function(){
var deferred = $q.defer();
deferred.resolve("hello")
return deferred.promise;
}
})
.controller('Controller', function(Service, $rootScope){
Service.ts().then(function(response){
$rootScope.title="hello";
changeRootPageNotFound();
});
function changeRootPageNotFound() {
$rootScope.title = "Page Not Found - 404";
$rootScope.titleSuffix = "";
}
});
Here is the html
<!DOCTYPE html>
<html>
<head>
<script data-require="[email protected]" data-semver="1.5.8" src="https://opensource.keycdn.com/angularjs/1.5.8/angular.min.js"></script>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body ng-app="Test">
<div ng-controller="Controller">
<h1>{{title}}</h1>
</div>
</body>
</html>
Please check this Plunker https://plnkr.co/edit/THXDYrWuTqR8UYSJlerB?p=preview
Upvotes: 1