Created
August 7, 2017 09:45
-
-
Save ahmadpriatama/a68f557a1b38416ba697d33226046d97 to your computer and use it in GitHub Desktop.
fetch.js
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 { 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