Reputation: 1338
I created a small example to learn about how to handle exceptions with promises particular in focus of my used MVC structure. This structure uses a Data Access Object (DAO) in addition to the 3 known components Model, View and Controller to be more independent from changes at the backend. Due to the conversion in the DAO you can use different methods to retrieve data from the backend. But I guess that's no new concept to you guys at all.
Well, what I want to know is this: If an exception occurs at the MovieInfoService
, the code jumps to the getMovieFailed
method and returns $q.reject(e)
. But what happens next? Does the DAO receive something and how does it gets processed?
I am pretty unfamiliar with the concept of error and exception handling in angular. Therefore I have no clue how to handle such problems with promises. Can you guys help me out and provide me with some useful hints, tips or advice how to handle such problems in order to show these problems on the users view to inform him? Actually even an alert()
will be enough - I just need to understand the basic idea/concept of handling exceptions with promises.
Here is some sample code of mine:
app.controller('MainController', ['$scope', 'MovieInfoDAO', function ($scope, MovieInfoDAO)
{
var vm = this;
vm.movie = {};
MovieInfoDAO.getMovie()
.then(function(data){
vm.movie = data;
});
activate();
//////////
function activate() {
return getMovieDetails().then(function(){
console.log('Starting Movie Search');
});
}
function getMovieDetails() {
return MovieInfoDAO.getMovie().then(function(data) {
vm.movie = data;
return vm.movie;
}
}
}]);
app.service("MovieInfoDAO", ['$q', 'MovieInfoService', function($q, MovieInfoService)
{
this.getMovie = function()
{
return MovieInfoService.getMovie().then(function(returnData){
var arrInfoItems = [];
for(var i = 0, length = returnData.length; i < length; i++){
var item = new MovieInfoModel(returnData[i]);
arrInfoItems.push(item);
}
return arrInfoItems;
});
};
}]);
app.service('MovieInfoService', ['$http', '$q', function($http, $q) {
this.getMovie = function()
{
return $http({
method: "GET",
data: { },
url: "http://www.omdbapi.com/?t=Interstellar&y=&plot=short&r=json"
})
.then(getMovieCompleted);
.catch(getMovieFailed);
};
function getMovieCompleted(response) {
return response.data;
}
function getMovieFailed(e) {
var newMessage = 'Failed to retrieve Infos from the Server';
if (e.data $$ e.data.description) {
newMessage = newMessage + '\n' + e.data.description;
}
e.data.description = newMessage;
return $q.reject(e);
}
return this;
}]);
function MovieInfoModel(arrParameter){
Model.call(this);
this.title = arrParameter.Title;
this.actors = arrParameter.Actors;
this.plot = arrParameter.Plot;
this.constructor(arrParameter);
}
HTML
<div>
<h1>{{Main.movie.title}}</h1>
<span>{{Main.movie.plot}}</span>
<br/>
<h3>Actors:</h3>
<span>{{Main.movie.actors}}</span>
</div>
Upvotes: 2
Views: 289
Reputation: 20152
I always create my service for ajax calls which is encapsulating $http service. In such service we can create one error handler for all requests. It enables to create many error types and check http response codes like 404,500. Some short example how it can look like, I added only get method:
var app=angular.module('app', []);
app.service('$myAjax', function($http) {
this.get = function (url,success,error) {
return $http.get(url).then(function(response){
if (response.data.status===1)//status is example success code sended from server in every response
return success(response.data);
else{
//here error handler for all requests
console.log("Something is wrong our data has no success on true.");
//error callback
return error(response.data);
}
},function(response){
//this code will run if response has different code than 200
//here error handler for all requests
console.log("Something is very wrong. We have different then 200 http code");
//error callback
return error(response.data);
});
}
});
//TEST
app.controller("Test",function($myAjax){
$myAjax.get('http://jsfiddle.net/echo/jsonp/',function(response){
//here success
return 1;
},function(response){
//here error
return 0;
}).then(function(data){
console.log("I am next promise chain");
console.log("Data from callbacks:"+data);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="Test">
</div>
</div>
I show error even if http code is 200 when data has no status
parameter on 1, this is second and internal error handling proposition. Thanks that parameter We can for example send many status information and create for them callbacks. Status 2 can mean - no rights, status 3 - no data etc..
Upvotes: 2
Reputation: 34217
If your intensions is to return the array arrInfoItems
in MovieInfoDAO.getMovie()
, instead of:
return arrInfoItems;
use a promise, e.g.:
app.service("MovieInfoDAO", ['$q', 'MovieInfoService', function($q, MovieInfoService)
{
this.getMovie = function()
{
var def = $q.defer();
MovieInfoService.getMovie()
.then(function(returnData){
var arrInfoItems = [];
for(var i = 0, length = returnData.length; i < length; i++){
var item = new MovieInfoModel(returnData[i]);
arrInfoItems.push(item);
}
def.resolve(arrInfoItems);
}, def.reject);
return def.promise;
};
}]);
Usage
app.controller('MainController', ['$scope', 'MovieInfoDAO', function ($scope, MovieInfoDAO)
{
var vm = this;
vm.movie = {};
MovieInfoDAO.getMovie()
.then(function(data){
vm.movie = data;
}, function(error){
// Handle error here, can be placed in a vm.error variable
});
}]);
Upvotes: 1