then(successCallback, errorCallback) ;always(callback) ;$http - service to perform AJAX requests;$timeout - AngularJS-wrapper over setTimeout ;$q - service to create your deferred-objects and promises.  var responseData; $http.get('http://api/user').then(function(response){ responseData = response.data; });   var User = function(data){ return angular.extend(this, data); }; $httpBackend.expectGET('http://api/user').respond(200, { result: { data: [{name: 'Artem'}], page: 1, total: 10 } }); var data = {}; $http.get('http://api/user').then(function(response){ var usersInfo = {}; usersInfo.list = _.collect(response.data.result.data, function(u){ return new User(u); }); usersInfo.total = response.data.result.total; return usersInfo; }).then(function(usersInfo){ data.users = usersInfo; }); then you can build a multi-layered application. ApiWrapper made a request, executed common error handlers, gave the data from the response unchanged to the next layer. There, the data was transformed as necessary and given to the next. Etc.then will come in success - callback following then . They did not return anything - in the success-callback will come undefined (see tests).reject , you need to return $q.reject(value) .  $httpBackend.expectGET('http://api/user').respond(400, {error_code: 11}); var error; $http.get('http://api/user').then( null, function(response){ if (response.data && response.data.error_code == 10){ return { list: [], total: 0 }; } return $q.reject(response.data ? response.data.error_code : null); } ).then( null, function(errorCode){ error = errorCode; } );   $httpBackend.expectGET('http://api/user/10').respond(200, {id: 10, name: 'Artem', group_id: 1}); $httpBackend.expectGET('http://api/group/1').respond(200, {id: 1, name: 'Some group'}); var user; $http.get('http://api/user/10').then(function(response){ user = response.data; return $http.get('http://api/group/' + user.group_id); }).then(function(response){ user.group = response.data; }); $q.all(...) accepts an array or dictionary of promises, combines them into one that will be resolved when all promises are resolved, or rejected with an error, when at least one promise is rejected. The values will come in success-callback either as an array or as a dictionary, depending on how the all method was called.  $httpBackend.expectGET('http://api/obj1').respond(200, {type: 'obj1'}) var obj1, obj2; var request1 = $http.get('http://api/obj1'); var request2 = $timeout(function(){ return {type: 'obj2'}; }); $q.all([request1, request2]).then(function(values){ obj1 = values[0].data; obj2 = values[1]; }); expect(obj1).toBeUndefined(); expect(obj2).toBeUndefined(); $httpBackend.flush(); expect(obj1).toBeUndefined(); expect(obj2).toBeUndefined(); $timeout.flush(); expect(obj1).toEqual({type: 'obj1'}); expect(obj2).toEqual({type: 'obj2'});   $q.all({ obj1: $http.get('http://api/obj1'), obj2: $timeout(function(){ return {type: 'obj2'}; }) }).then(function(values){ obj1 = values.obj1.data; obj2 = values.obj2; });   spyOn(UserApi, 'get').andReturn($q.when({id: 1, name: 'Artem'})); var res; UserApi.get(1).then(function(user){ res = user; }); $rootScope.$digest(); expect(res).toEqual({id: 1, name: 'Artem'}); $digest loop must be executed.deferred objects$q -service also allows you to wrap any asynchronous operation in your deferred-object with the corresponding promise-object.  var postFile = function(name, file) { var deferred = $q.defer(); var form = new FormData(); form.append('file', file); var xhr = new XMLHttpRequest(); xhr.open('POST', apiUrl + name, true); xhr.onload = function(e) { if (e.target.status == 200) { deferred.resolve(); } else { deferred.reject(e.target.status); } if (!$rootScope.$$phase) $rootScope.$apply(); }; xhr.send(form); return deferred.promise; }; var deferred = $q.defer()deferred.resolve()reject in case of error: deferred.reject(e.target.status)return deferred.promise  $rootScope.resPromise = $timeout(function(){ return 10; }); var res = $rootScope.$eval('resPromise + 2'); expect(res).toBe(2); $timeout.flush(); res = $rootScope.$eval('resPromise + 2'); expect(res).toBe(12); watch , then exactly the resolved value will come as a value.  var res; $rootScope.resPromise = $timeout(function(){ return 10; }); $rootScope.$watch('resPromise', function(newVal){ res = newVal; }); expect(res).toBeUndefined(); $timeout.flush(); expect(res).toBe(10);   $rootScope.resPromise = function(){ return $timeout(function(){ return 10; }); }; var res = $rootScope.$eval('resPromise()'); expect(typeof res.then).toBe('function'); catch(errorCallback) as a shortened synonym for promise.then(null, errorCallback) ;always(callback) renamed finally(callback) ;promise.then looks like then(successCallback, errorCallback, progressCallback) , while deferred has a notify(progress) method.
Source: https://habr.com/ru/post/189084/
All Articles