Last active
October 14, 2016 19:25
-
-
Save alecklandgraf/f9d48177b3483041de6762f4cfb4d698 to your computer and use it in GitHub Desktop.
Angular 1.5 design pattern for a cached API resource
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import angular from 'angular'; | |
import assignIn from 'lodash/assignIn'; | |
const meServiceModule = angular.module('meServiceModule', []); | |
meServiceModule.factory('meService', ['$http', '$q', ($http, $q) => { | |
const user = {}; | |
const state = { | |
loaded: false, | |
promiseInFlight: false, | |
loadingPromise: null, | |
}; | |
/** | |
* fetchMe - fetches the user's profile from memory or the API | |
* | |
* fetchMe will try to load the user's profile from the angular service singleton falling back to | |
* fetching from the API. If a request is in flight, fetchMe will return the current request's promise | |
* preventing race conditions causing multiple requests to the API. | |
* | |
* Usage: | |
* meService.fetchMe().then(user => { | |
* $scope.user = user; | |
* }); | |
* | |
* @return {Promise} resolves to the user's profile data | |
*/ | |
function fetchMe() { | |
if (state.promiseInFlight) { | |
return state.loadingPromise; | |
} | |
if (!state.loaded) { | |
state.promiseInFlight = true; | |
state.loadingPromise = $http({ | |
method: 'GET', | |
url: '/api/me', | |
}) | |
.then(resp => resp.data) | |
.then(data => { | |
state.promiseInFlight = false; | |
state.loaded = true; | |
assignIn(user, data); // your API's data | |
return user; | |
}); | |
return state.loadingPromise; | |
} | |
return $q.when(user); // similar to Promise.resolve(user) | |
} | |
return { | |
fetchMe, | |
}; | |
}]); | |
export default meServiceModule.name; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment