Continuation return function inside resolution function as continuation

Context

I work with Angular. I have a service called UserService that handles login, authentication and user data requests.

The get method should check if the user has a valid (not expired) token for authentication before executing the get request. So, if so, make a request; if not, request a token and then execute the request.

Problem

This get method must hide its complex requests. He should return only the promise, since he makes only one request.

So, an example of use:

 UserService .get() .then(data => { ... }) .catch(error => { ... }) 

Wrong decision

Check if the token has expired. If so, return the request to update the token, and there, enter and return the request for receipt. If this is not the case, simply enter and return the request for receipt. As below:

 function get() { if (isTokenExpired(token)) return $http .post(url + '/refreshtoken', 'token=' + refreshToken) .then(response => { token = response.data.token return $http.get(url + '?token=' + token) }) .catch(response => { ... }) else return $http.get(url + '?token=' + token) } 

But this returns a promise that I will have to handle this:

 UserService .get() .then(request => { request // THAT IS NOT GOOD .then(data => { ... }) .catch(error => { ... }) }) .catch(error => { ... }) 

Something like a usage example!

The right decision

How to make this get method for a service that processes this authentication and hides everything from the controller that it will use, allowing it as in the use case?

+7
javascript angularjs asynchronous
source share
2 answers

But this returns a promise to promise that I will have to handle it like this:

  UserService.get().then(request => { request.then(data => { … }) }) 

Not.

Promises to make a chain , any promise to promise to implicitly be smoothed to the promise of an internal result. Your "wrong decision" code just works as it is.

+3
source share

Here is an example. Basically you need to convert using optional .then()

 angular.module('app', []) .service('UserService', function($http) { let url = 'https://jsonplaceholder.typicode.com'; function getUserData(token) { return $http.get(url + '/users/1', { token: token }) .then(resp => resp.data); } this.get = function(tokenIsValid) { if (!tokenIsValid){ console.log('refreshing'); return $http.post(url + '/posts', { refreshToken: 'rt' }) .then(getUserData) } return getUserData(); } return this; }) .run(function($rootScope, UserService) { $rootScope.get = (valid) => { console.log('Getting with ' + (valid? '':'in') + 'valid token'); UserService.get(valid) .then(console.log) .catch(console.error); } }); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="app"> <button ng-click="get()">Get invalid</button> <button ng-click="get(true)">Get valid</button> </div> 
0
source share

All Articles