Fetch API exercise
A job interview exercise for a position requiring knowledge of ES6 features. This utility translates parameterized filter options, then retrieves and transforms JSON data from an Express endpoint using the Fetch API/Promises, a third-party URI manipulation library, and a Fetch API transpilation polyfill.
managed-records.js:
import fetch from "../util/fetch-fill";
import URI from "urijs";
window.path = "http://[IP REMOVED]/records";
// Record transformation function
function retrieve(options = { page: 1, colors: [] }) {
// Default properties before request if we get passed an empty options object
options.page = (options.hasOwnProperty('page')) ? options.page : 1;
options.colors = (options.hasOwnProperty('colors')) ? options.colors : [];
// Translate function args into the inputs expected by the API
let transformed_options = {
limit: 10,
offset: 10 * (options.page-1),
'color[]': options.colors
};
// Set up the endpoint URI using the translated options
let uri = URI(window.path).addSearch(transformed_options).normalize();
// Emit a promise object
return fetch(uri).then(response => {
// Pass data along the chain for manipulations
if (response.ok) {
return response.json();
}
// Report any bad API responses to the console
throw new Error(`Invalid HTTP response (${response.statusCode}): ${response.statusText}`);
}).then(records => {
// Get some variables ready to build the translated return object
let keys = [],
open_records = [],
closed_primary = 0,
primary_colors = ['red', 'blue', 'yellow'],
prev_page_id = options.page - 1,
next_page_id = options.page + 1;
// Make sure we have correct page numbers for first and last pages
prev_page_id = (prev_page_id !== 0) ? prev_page_id : null;
// TODO: Next page number logic... How do we know if this is the last page without making a second request?
// Iterate over the passed response object
records.forEach(record => {
// Get the record ID
keys.push(record.id);
// Either add the record to the open records array...
if (record.disposition === 'open') {
open_records.push(record);
} else if (primary_colors.contains(record.color)) {
// ...or increment the closed records counter
++closed_primary;
}
});
// Hand back the manipulated object in the specified format
return {
ids: keys,
open: open_records,
closedPrimaryCount: closed_primary,
previousPage: prev_page_id,
nextPage: next_page_id
};
}).catch(error => {
// Report any exceptions to the console
throw new Error('Error: ' + error.message);
});
}
export default retrieve;