Skip to content

Instantly share code, notes, and snippets.

@alecklandgraf
Last active October 14, 2016 19:25
Show Gist options
  • Save alecklandgraf/f9d48177b3483041de6762f4cfb4d698 to your computer and use it in GitHub Desktop.
Save alecklandgraf/f9d48177b3483041de6762f4cfb4d698 to your computer and use it in GitHub Desktop.
Angular 1.5 design pattern for a cached API resource
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