Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ahmadpriatama/a68f557a1b38416ba697d33226046d97 to your computer and use it in GitHub Desktop.
Save ahmadpriatama/a68f557a1b38416ba697d33226046d97 to your computer and use it in GitHub Desktop.
fetch.js
import { config } from '../config';
import validator from 'is-my-json-valid';
import cloneDeep from 'lodash/cloneDeep';
const addAdditionalProperties = (schema) => {
if (schema.type === 'object') {
return Object.assign({}, schema, {
additionalProperties: false,
properties: Object.entries(schema.properties).reduce((acc, [key, value]) => {
if (value.type === 'object' || value.type === 'array') {
acc[key] = addAdditionalProperties(value);
} else {
acc[key] = value;
}
return acc;
}, {}),
});
} else if (schema.type === 'array') {
return Object.assign({}, schema, {
items: Object.assign({}, schema.items, {
additionalProperties: false,
}),
});
}
return schema;
};
export const fetchRetry = (url, options) => {
const retries = 3;
const delay = 0;
return new Promise((resolve, reject) => {
let count = 1;
const attempt = () => fetch(url, options)
.then((response) => {
if (!response.ok) {
throw Error(response.statusText);
}
resolve(response);
})
.catch((error) => {
if (count < retries) {
count += 1;
if (delay) {
setTimeout(attempt, delay);
} else {
attempt();
}
} else {
reject(error);
}
});
attempt();
});
};
export const fetchData = async ({
serviceName,
params,
callback,
schema = null,
additionalSchemas = null,
endpoint = 'API',
method = 'POST',
additionalHeaders = {},
}) => {
let urlPrefix = config.url;
if (endpoint === 'EP') {
urlPrefix = config.urlEP;
}
let headers = { "content-type":"application/x-www-form-urlencoded" };
if (endpoint === 'EP') {
headers = { "X-API":"Stay Hungry Stay Foolish." };
}
Object.assign(headers, additionalHeaders);
return fetchRetry(urlPrefix + serviceName, {
method,
headers,
credentials: "include",
body: params
})
.then((response) => response.json())
.then((json) => {
if (schema) {
let validate;
let successSchema = schema;
let failedSchema = schema;
if (Array.isArray(schema)) {
successSchema = schema[0];
failedSchema = schema[1];
}
if (json.success === false) {
validate = validator(failedSchema);
} else {
validate = validator(successSchema);
}
if (validate(json)) {
if (additionalSchemas) {
const output = Object.entries(additionalSchemas).reduce((acc, [key, value]) => {
const validateChild = validator(value);
const jsonClone = cloneDeep(json);
acc[key] = false;
if (validateChild(jsonClone)) {
const filter = validator.filter(addAdditionalProperties(value));
acc[key] = filter(jsonClone);
}
return acc;
}, {});
callback(output);
return output;
}
let schemaForFilter = addAdditionalProperties(successSchema);
if (json.success === false) {
schemaForFilter = addAdditionalProperties(failedSchema);
}
const filter = validator.filter(schemaForFilter);
const filteredJSON = filter(json);
callback(filteredJSON);
return filteredJSON;
}
callback();
return { success: false };
} else {
callback(json);
return json;
}
}).catch(() => {});
};
export const myFetch = (
serviceName,
params,
callback,
) => fetchData({
serviceName,
params,
callback,
});
export default {
myFetch,
fetchData,
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment