Skip to content

Instantly share code, notes, and snippets.

@dievardump
Last active February 26, 2020 16:05
Show Gist options
  • Save dievardump/63dd36ae0f9842cf556880aa6a7ecaa4 to your computer and use it in GitHub Desktop.
Save dievardump/63dd36ae0f9842cf556880aa6a7ecaa4 to your computer and use it in GitHub Desktop.
Fetch wrapper
/**
Usage
To set default values, used for every request :
fetcher.setMode('include');
fetcher.setHeader('include');
// to make a request
fetcher() // builds a fetcher instance
.get(url, options) //
.then(json)
.catch(err)
fetcher()
.post(url, options)
.then(blob => {})
.catch(err => {})
fetcher()
.blob() // set resolver for next query as a blob
.post(url, options)
.then(blob => {})
.catch(err => {})
fetcher()
.text() // set resolver for next query as a text
.post(url, options)
.then(text => {})
.catch(err => {})
*/
const headers = [];
let mode = "same-origin";
let credentials = "include";
let defaultResolver = "json";
const resolvers = {
json: res => res.json(),
blob: res => res.blob(),
text: res => res.text(),
};
function buildHeaders(rqHeaders = new Headers()) {
headers.forEach(h => rqHeaders.append(h.name, h.value));
return rqHeaders;
}
const status = res => {
if (res.status >= 400) {
return Promise.reject(res);
}
return Promise.resolve(res);
};
const fetcher = function() {
let nextResolver = null;
function make(method, url, options = {}) {
if (options.headers && !(options.headers instanceof Headers)) {
throw new Error("options.headers should be an instance of Headers");
}
const data = {
method,
mode: options.mode || mode,
credentials: options.credentials || credentials,
headers: buildHeaders(options.headers)
};
if (method !== "GET") {
let body = options.body;
// if body is an object that is not a FormData
if (body && typeof body !== "string" && !(body instanceof FormData)) {
// convert the object into JSON
body = JSON.stringify(body);
// and set Content-Type to json
data.headers.set("Content-Type", "application/json");
}
data.body = body;
}
return makeRequest(url, data);
}
const resolve = res => {
let resolver = nextResolver || resolvers[defaultResolver];
// reset nextResolver to null so it uses the default one
nextResolver = null;
return resolver(res);
};
function makeRequest(url, options = {}) {
return fetch(url, options)
.then(status)
.then(resolve)
.catch(err => Promise.reject(err));
}
return {
// set the next request resolver as a blob resolver
blob() {
nextResolver = resolvers.blob;
return this;
},
// set the next request resolver as a json resolver
json() {
nextResolver = resolvers.json;
return this;
},
//get request
get(url, options = {}) {
return make.apply(this, ["GET", url, options]);
},
//post request
post(url, options = {}) {
return make.apply(this, ["POST", url, options]);
},
//put request
put(url, options = {}) {
return make.apply(this, ["PUT", url, options]);
},
//patch request
patch(url, options = {}) {
return make.apply(this, ["PATCH", url, options]);
},
//delete request
del(url, options = {}) {
return make.apply(this, ["DELETE", url, options]);
}
};
};
// set default mode for requests
fetcher.setMode = newMode => {
mode = newMode;
return fetcher;
};
// set default credentials for request
fetcher.setCredentials = newCedentials => {
credentials = newCedentials;
return fetcher;
};
//set default resolver
fetcher.setResolver = name => {
if (resolvers[name]) {
defaultResolver = name;
} else {
throw new Error("Resolver not found");
}
return fetcher;
};
// set permanent header value sent with all requests
fetcher.setHeader = (name, value) => {
if (typeof name !== "string") {
throw new Error("Name of the header should be a String");
}
headers.push({
name: name,
value: value
});
return fetcher;
};
//remove a Header from the permanent header list
fetcher.removeHeader = name => {
if (typeof name !== "string") {
throw new Error("Name of the header should be a String");
}
let length = headers.length;
for (let i = 0; i < length; i++) {
if (headers[i].name === curr.name) {
headers.splice(i, 1);
i--;
length--;
}
}
return fetcher;
};
if (process.env.NODE_ENV === "development") {
window.fetcher = fetcher;
}
export default fetcher;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment