Skip to content

Cookbook: main

Eugene Lazutkin edited this page Feb 28, 2020 · 17 revisions

The main functionality of heya-io is in file io.js, which should be included. As a general entry point it uses main.js, which includes the main API, and includes and enables track, cache, and bundle services.

See How to include for more details. See main for the full documentation.

Make GET request

io.get('/url').then(function (value) {
  console.log('got:', value);
});

Make GET request with a query

io.get('/url', {a: 1, b: 'x'}).then(function (value) {
  // GET /url?a=1&b=x
  console.log('got:', value);
});

POST a form

Let's POST a form (may include files, or any other form elements):

var formElement = document.querySelector('form');
io.post('/form', new FormData(formElement));

Use custom headers

io.get({
  url:     '/url',
  headers: {'Accept': 'application/xml', 'X-Token': 123}
}).then(function (value) {
  console.log('got:', value);
});

Make various REST requests

function done() { console.log('done'); }

io.post('/things', {name: 'Bob', age: 42}).then(done);
io.put('/things/5', {name: 'Alice', age: 33}).then(done);
io.patch('/things/7', {age: 14}).then(done);
io.remove('/things/3').then(done); 

Check if a resource is present

io.head('/url', {q: 1}).then(function () {
  console.log('present');
}).catch(function () {
  console.log('missing');
});

Check for an error

io.get('/url').then(function (value) {
  // do something with value
}).catch(function (value) {
  if (value instanceof io.BadStatus) {
    console.log('Bad server status:', value.xhr.status);
  } else if (value instance io.TimedOut) {
    console.log('I/O has timed out');
  } else if (value instance io.FailedIO) {
    console.log('Cannot initiate an I/O request');
  } else {
    console.log('Error:', value);
  }
});

Check for headers

io.get({
  url: '/url',
  returnXHR: true
}).then(function (xhr) {
  console.log('Content-Type:', xhr.getResponseHeader('Content-Type'));
});

Work with raw XHR result

io.get({
  url: '/url',
  returnXHR: true
}).then(function (xhr) {
  console.log('Status:', xhr.status, ' ', xhr.statusText);
  if (xhr.responseType === 'json') {
    console.log('JSON payload:', xhr.response);
  } else if (/^application\/json\b/.test(xhr.getResponseHeader('Content-Type'))) {
    console.log('JSON payload:', JSON.parse(xhr.responseText));
  }
});

Run several requests sequentially

io.get('/url', {q: 1}).then(function (value) {
  return io.get('/url', {q: value.id});
}).then(function (value) {
  return io.get('/url', {q: value.id});
}).then(function (value) {
  console.log('Final result:', value);
}).catch(function (value) {
  console.log('Error while executing:'. value.options);
});

Run several requests in parallel

Using Promise.all():

Promise.all([
  io.get('/url', {q: 1}),
  io.get('/url', {q: 2})
]).then(values => {
  values.forEach((value, index) => console.log('Request #' + index ':', value));
}).catch(error => console.log('Some request has failed: ', error));

Using heya-async:

async.par(
  [io.get('/url', {q: 1}), io.get('/url', {q: 2})],
  io.Deferred // we will use the same deferred
).then(function (values) {
  values.forEach(function (value, index) {
    if (value instance io.FailedIO) {
      console.log('Request #' + index + ' has failed.');
    } else {
      console.log('Request #' + index ':', value);
    }
  });
});

Virtualize hosts

Use pseudo-hosts in a program, but keep actual URLs in settings:

const redirects = {
  $widgets: 'https://widgets.example.com/api/2',
  $gadgets: 'https://gadgets.example.com/api/1'
};
const redirectSources = Object.keys(redirects);

const prevProcessOptions = io.processOptions;
io.processOptions = options => {
  options = prevProcessOptions(options);

  for (let i = 0; i < redirectSources.length; ++i) {
    const redirect = redirectSources[i];
    if (redirect.length && options.url.substr(0, redirect.length) === redirect &&
        options.url.charAt(redirect.length) === '/') {
      const newOptions = Object.create(options);
      newOptions.url = redirects[redirect] + newOptions.url.substr(redirect.length);
      return newOptions;
    }
  }

  return options;
};

How to use it:

// GET https://widgets.example.com/api/2/123
const data = await io.get('$widgets/123');

Build a URL

Use a URL outside of heya:

const getUrl = options => {
  if (typeof options == 'string') options = {url: options};
  return io.buildUrl(io.processOptions(options));
};

How to use it:

const url = getUrl({url: '$widgets/-list', query: {a: 1}});
// https://widgets.example.com/api/2/-list?a=1

const a = document.getElementById('myAnchor');
a.href = url;
// <a id="myAnchor" href="https://widgets.example.com/api/2/-list?a=1">link</a>