-
-
Save martynchamberlin/904e791f250eb151e2aec09dbea2d94d to your computer and use it in GitHub Desktop.
A really squirrelly way to mock a promise library. Don't actually use this!
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
/** | |
* This is a lightweight wrapper that mimics Angular's $http service. | |
* The reason for this is twofold: | |
* | |
* (1) Often, two or more components will need the exact | |
* same resource at the same time. This should only result in | |
* one HTTP request but it should resolve both correctly. Angular's | |
* {cache: true} argument in $http.get handled this well. | |
* | |
* (2) A component will sometimes need a resource later on in a | |
* page state that a different component previously fetched. Except | |
* in cases of polling, this also results in situation in which a | |
* cached version must be fetched. Angular's {cache: true} also ensured this. | |
* | |
* The flags of "loading" and "resolved" in this wrapper keep the | |
* implementing classes from having to worry about these details, unless | |
* they're needed for UI feedback. The goal is that we should be able to | |
* make a GET call without ever having to worry about how many HTTP requests | |
* are being generated, while still having a guarantee that the callback will | |
* fulfilled as soon as the data is ready. | |
* | |
* Our usage example demonstrates that this API looks and feels just like | |
* the Angular service we're used to. The only difference is that unlike | |
* Angular's $http service, we default cache to true, not to false. | |
* | |
* ``` | |
* import $http from '../shared/http'; | |
* | |
* $http.get('some url').then((response) => { | |
* console.log(response); | |
* }).error((response) => { | |
* console.log(response); | |
* }); | |
* ``` | |
*/ | |
import axios from 'axios'; | |
const getUrls = {}; | |
module.exports = { | |
get: (url, opts) => { | |
const defaultOptions = { | |
cache: true | |
}; | |
const options = Object.assign({}, defaultOptions, opts); | |
if (!getUrls[url]) { | |
getUrls[url] = { | |
response: null, | |
loading: false, | |
resolved: false, | |
successCallbacks: [], | |
errorCallbacks: [], | |
}; | |
} | |
if (options.cache === false || | |
(getUrls[url].resolved === false && getUrls[url].loading === false)) { | |
getUrls[url].loading = true; | |
axios.get(url).then((response) => { | |
getUrls[url].loading = false; | |
getUrls[url].resolved = true; | |
getUrls[url].response = response; | |
// loop through all of our callbacks and fire them | |
getUrls[url].successCallbacks.map(callback => callback(response)); | |
// reset all the callbacks | |
getUrls[url].callbacks = []; | |
}).catch((response) => { | |
getUrls[url].loading = false; | |
getUrls[url].resolved = true; | |
getUrls[url].errorCallbacks.map(callback => callback(response)); | |
}); | |
} | |
return { | |
then: (callback) => { | |
if (options.cache === true && getUrls[url].resolved === true) { | |
callback(getUrls[url].response); | |
} else { | |
// Store this callback to be called when we've resolved | |
getUrls[url].successCallbacks.push(callback); | |
} | |
}, | |
error: (callback) => { | |
if (options.cache === true && getUrls[url].resolved === true) { | |
callback(getUrls[url].response); | |
} else { | |
// Store this callback to be called when we've resolved | |
getUrls[url].errorCallbacks.push(callback); | |
} | |
} | |
}; | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment