UNPKG

instantjob-recruiter-client

Version:

a set of tools for creating an instantjob recruiter react client

175 lines (156 loc) 4.88 kB
import 'whatwg-fetch' import superagent from 'superagent' import {api_path, DEV} from 'common/constants' import store from 'common/store' import {array_contains} from 'common/utilities' import auto_bind from 'common/auto_bind' export function make_url(endpoint) { return `${api_path}/${endpoint}.json?` } const authentication_headers = () => { const {token} = store.getState().authentication if (token) { return { 'Authorization': `Bearer ${token}` } } return {} } const requestWithMethod = function(method, endpoint, data = {}) { var options = {method} let params = "" if (method == 'GET' && data !== null) { for (var key in data) { params += encodeURIComponent(key) + "=" + encodeURIComponent(data[key]) + "&" } data = null } options.headers = authentication_headers() if (data !== null) { options.body = JSON.stringify(data) options.headers = { ...options.headers, 'Accept': 'application/json', 'Content-Type': 'application/json', } } var request_url = `${make_url(endpoint)}${params}` return fetch(request_url, options) .catch((error) => { return new Promise((resolve, reject) => { DEV && console.log(method, request_url, data) DEV && console.log(error) return reject(error) }) }) .then((response) => { return new Promise((resolve, reject) => { if (response == null || response.error || (array_contains([400, 404, 422, 500], response.status))) { reject(response) } else if (response.status != 204) { response.json() .then((responseObject) => { if (responseObject == null || responseObject.error || (array_contains([400, 404, 422, 500], responseObject.status))) { reject(responseObject) } else { resolve(responseObject) } }) .catch((error) => reject(error)) } else { resolve(response) } }) }) } const request = { get: function(endpoint, params, callback) { return requestWithMethod('GET', endpoint, params, callback) }, post: function(endpoint, data, callback) { return requestWithMethod('POST', endpoint, data, callback) }, put: function(endpoint, data, callback) { return requestWithMethod('PUT', endpoint, data, callback) }, delete: function(endpoint, data, callback) { return requestWithMethod('DELETE', endpoint, data, callback) }, asynchronous: function(endpoint, data) { return new Promise((resolve, reject) => { const poll_result = (asynchronous_request_id) => requestWithMethod('GET', `asynchronous_requests/${asynchronous_request_id}`) .then((asynchronous_request) => { switch (asynchronous_request.status) { case "pending": setTimeout(() => poll_result(asynchronous_request_id), 1000) break case "completed": resolve(JSON.parse(asynchronous_request.result)) break default: reject(asynchronous_request) } }) requestWithMethod('POST', endpoint, data) .then((response) => setTimeout(() => poll_result(response.asynchronous_request_id), 1000)) }) }, get_paginated: function(endpoint, data = {}, callback) { return new Promise((resolve, reject) => { const request_page = (page) => requestWithMethod('GET', endpoint, {...data, page}) .then((page_results) => { if (page_results.length == 0) { resolve() } else { callback(page_results) request_page(page + 1) } }) .catch(reject) request_page(1) }) }, upload(endpoint, file, data) { // request won't start if `then` is not called const request = superagent .put(make_url(endpoint)) .set(authentication_headers()) .accept('json') .attach('file', file) return Object.keys(data).reduce((request, key) => request.field(key, data[key]), request) }, delayed_put(endpoint, data) { return new Promise((resolve, reject) => { let delayed_request = delayed_requests[endpoint] if (delayed_request && !delayed_request.completed) { resolve = delayed_request.cancel(resolve) } delayed_requests[endpoint] = new DelayedRequest(() => request.put(endpoint, data), resolve, reject) }) } } const delayed_requests = {} class DelayedRequest { constructor(request, resolve, reject) { this.request = request this.resolve = resolve this.reject = reject auto_bind(this) setTimeout(this.run, 2 * 1000) } run() { this.completed = true if (!this.canceled) { this.request() .then(this.resolve, this.reject) } } cancel(resolve) { this.canceled = true return (...args) => { resolve(...args) this.resolve(...args) } } } export default request