Modern Fetch API wrapper for simplicity.

Related tags

API far-fetch
Overview

FarFetch Class

Modern Fetch API wrapper for simplicity.

Install

npm i @websitebeaver/far-fetch

Then include it in the files you want to use it in like so:

import FarFetch from '@websitebeaver/far-fetch';

// If you need to manually handle errors
import FarFetch, { FarFetchError } from '@websitebeaver/far-fetch';

Instantiating Class

const ff = new FarFetch();

This is how you'd create a class in its simplest form in FarFetch. You can check out all the options you can use here.

It is recommended to then import the initialized class on every page used.

Why Use FarFetch?

While JavaScript's native Fetch API was an amazing feature added, it introduced a myriad of inconsistencies, which cause you to have to copy and paste StackOverflow questions for simple boilerplate code often times. This is especially the case with uploading files and I find it hard to believe anyone just straight memorizes how to do it. There's so many things to think about. It would have been so much better in a unified experience.

The core philosophy of FarFetch to is keep things as similar as possible to native JavaScript fetch, and merely improve upon it. This way, you're not really learning a completely new API. Instead, the aim of this class is almost to pitch which features I think are missing in Fetch API. The aim of this class isn't to recreate the wheel, but rather, to improve upon Fetch API, with a super thin wrapper. The main advantages over vanilla Fetch are as follows:

  1. Ability to call syntactic sugar methods like ff.get(), ff.post(), ff.put, etc., rather than fetch(url, { method: 'GET' }). FarFetch allows both ways.
  2. Ability to "automatically" throw and handle errors for every call in a unified manner with a global error handler.
  3. Ability to use default init options on every call.
  4. Ability to do actions before every request withbeforeSend() and afterSend(response) hooks.
  5. Ability to pass data to each call in a consistent manner.
  6. Ability to upload files in a consistent manner.

Passing in Data to Request

Passing in data in Fetch API is exceedingly inconsistent. In this regard, it really took a step backwards from how jQuery implemented passing in data, in my opinion, at least from a usability standpoint. Of course Fetch API's body options offers more versatility, which is why FarFetch supports using body. However, it really shouldn't necessary in the majority of use cases. Adding data to a GET and POST request is done in two separate ways in Fetch API. GET requests must use appended URL query parameters, while POST requests generally use a stringified object used as the body property.

Fetch API

// GET
async getPerson() {
  const data = { name: 'Bobby Big Boy', gender: 'Male', age: 5 };

  const queryString = `?${new URLSearchParams(Object.entries(data))}`;

  const response = await fetch(`https://example.com/people${queryString}`, {
    method: 'GET',
  });

  if(!response.ok) throw new Error('Server error.');

  return response.json();
}

// POST
async addPerson() {
  const data = { name: 'Bobby Big Boy', gender: 'Male', age: 5 };

  const response = await fetch(`https://example.com/people`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data),
  });

  if(!response.ok) throw new Error('Server error.');

  return response.json();
}

// application/x-www-form-urlencoded
async addPerson() {
  const data = { name: 'Bobby Big Boy', gender: 'Male', age: 5 };

  const response = await fetch(`https://example.com/people`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams(Object.entries(data)),
  });

  if(!response.ok) throw new Error('Server error.');

  return response.json();
}

FarFetch

// GET
async getPerson() {
  const { responseJSON } = await ff.get('https://example.com/people', {
    data: { name: 'Bobby Big Boy', gender: 'Male', age: 5 },
  });

  return responseJSON;
}

// POST
async addPerson() {
  const { responseJSON } = await ff.post('https://example.com/people', {
    data: { name: 'Bobby Big Boy', gender: 'Male', age: 5 },
  });

  return responseJSON;
}

// application/x-www-form-urlencoded
async addPerson() {
  const { responseJSON } = await ff.post('https://example.com/people', {
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    data: { name: 'Bobby Big Boy', gender: 'Male', age: 5 },
  });

  return responseJSON;
}

Notice how each request is completely predictable in FarFetch and doesn't require you to throw an exception if it's not a status code in the 200-299 range (response.ok). Sure, using the native javascript Fetch API isn't horrible anymore in regular Javascript, thanks to features like URLSearchParams and Object.entries, but it's so much easier to not have to think much when you program. FarFetch's consistent API makes it a breeze to make any sort of request.

Uploading Files

Uploading One File

Fetch API

async uploadFile() {
  const [file] = document.querySelector('#my-file').files;

  const data = { name: 'Bobby Big Boy', gender: 'Male', age: 5 };

  const formData = new FormData();

  formData.append('file', file);

  Object.keys(data).forEach((key) => {
    formData.append(key, data[key]); // Add server data to formData
  });

  const response = await fetch('https://example.com/people', {
    method: 'POST',
    body: formData,
  });

  if(!response.ok) throw new Error('Server error.');
}

FarFetch

async uploadFile() {
  const [file] = document.querySelector('#my-file').files;

  await ff.post('https://example.com/people', {
    data: { name: 'Bobby Big Boy', gender: 'Male', age: 5 },
    files: file,
  });
}

Uploading Multiple Files

Fetch API

async uploadFiles() {
  const files = document.querySelector('#my-files').files;

  const data = { name: 'Bobby Big Boy', gender: 'Male', age: 5 };

  const formData = new FormData();

  Object.keys(data).forEach((key) => {
    formData.append(key, data[key]); // Add server data to formData
  });

  files.forEach((file) => {
    formData.append('files[]', file); // Add files array to formData
  });

  await fetch('https://example.com/people', {
    method: 'POST',
    body: formData,
  });

  if(!response.ok) throw new Error('Server error.');
}

FarFetch

async uploadFiles() {
  const files = document.querySelector('#my-files').files;

  await ff.post('https://example.com/people', {
    data: { name: 'Bobby Big Boy', gender: 'Male', age: 5 },
    files,
  });
}

Uploading Multiple Files with Distinct File Names

Fetch API

async uploadFiles() {
  const photos = document.querySelector('#photos').files;
  const videos = document.querySelector('#videos').files;
  const documents = document.querySelector('#documents').files;

  const data = { name: 'Bobby Big Boy', gender: 'Male', age: 5 };

  const formData = new FormData();

  Object.keys(data).forEach((key) => {
    formData.append(key, data[key]); // Add server data to formData
  });

  photos.forEach((photo) => {
    formData.append('photos[]', photo); // Add files array to formData
  });

  videos.forEach((video) => {
    formData.append('videos[]', video); // Add files array to formData
  });

  documents.forEach((document) => {
    formData.append('documents[]', document); // Add files array to formData
  });

  await fetch('https://example.com/people', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: formData,
  });

  if(!response.ok) throw new Error('Server error.');
}

FarFetch

async uploadFiles() {
  const photos = document.querySelector('#photos').files;
  const videos = document.querySelector('#videos').files;
  const documents = document.querySelector('#documents').files;

  await ff.post('https://example.com/people', {
    data: { name: 'Bobby Big Boy', gender: 'Male', age: 22 },
    files: { photos, videos, documents },
  });
}

Look at how much more comprehensible the code becomes with FarFetch. This is practically even readable by a non-programmer, as this reads as: Let's add a 22 year old man named Bobby and upload his following files: photos, videos and documents.

Passing in Fetch API init options

FarFetch accepts all Fetch API init options. It's even possible to pass in the native fetch body, though its use is discouraged in most cases, in favor of, FarFetch's data parameter.

Set Options for Single Request

await ff.get('https://example.com', {
  headers: { 'Content-Type': 'application/json' },
  cache: 'reload',
})

Set Global Options for Every Request

This is really handy for when you know for a fact you will be using the same options on either every request or nearly all. You can accomplish this by declaring these options when you instantiate FarFetch.

const ff = new FarFetch({
  headers: { 'Content-Type': 'application/json' },
  cache: 'reload',
});

Sometimes you might not want to set a particular option when FarFetch is created. Let's say you're using a login system. You don't want to have the JWT be evaluated when you instantiate the class, since it won't work properly if a user accesses the page logged out. The header would never reevaluate. This is why FarFetch has allows you to return options you want to use on specific conditions on the global beforeSend() function. These options will then get deep merged, with the beforeSend() return taking precedence. Obviously passing options into a specific request will take the highest precedence of them all, however.

const ff = new FarFetch({
  headers: { 'Content-Type': 'application/json' },
  cache: 'reload',
  beforeSend() {
    // Use authorization header if token set in localStorage
    if (localStorage.getItem('token')) {
      return {
        headers: {
          'Content-Type': 'text/plain',
          Authorization: `Bearer ${localStorage.getItem('token')}`,
        },
      };
    }
  },
});

So if you're logged in, your request would have the following options.

{
  headers: {
    'Content-Type': 'text/plain',
    Authorization: `Bearer ${localStorage.getItem('token')}`,
  },
  cache: reload,
}

Notice how the Content-Type is set to text/plain, rather than application/json. As stated before, this is because the return on beforeSend() takes precedence on the deep merge.

Getting Response

Retrieving Response Data

FarFetch returns a Response object, so you can use the Body methods: arrayBuffer(), blob(), formData(), json() and text(). This is exactly how you'd be doing it in native Fetch as well.

FarFetch supports the vanilla Fetch way of retrieving data, by awaiting for the the Response Body and transforming it to your type.

const response = await ff.get('https://example.com/people');

const responseJSON = await response.json();

return responseJSON;

You can also use FarFetch's handy responseJSON and responseText properties for your convenience, instead of having to await for either response.json() or response.text(), if the response header type is either application/json or text/plain, respectively. These are properties that were simply added to the Response object. What's also nice about this is that it ensures that getting the JSON won't result in an error, due to a mismatch in header, as FarFetch checks for this already, internally.

const { responseJSON } = await ff.get('https://example.com/people');

return responseJSON;
const { responseText } = await ff.get('https://example.com/people');

return responseText;

Set Base URL

Most applications will likely use the same domain for most or even all requests. FarFetch has a baseURL option you can use when you instantiate the class.

const ff = new FarFetch({
  baseURL: 'https://example.com',
});

Now request like the following will work.

await ff.get('/people');

But what if you want to use a different base URL for just a few requests in your application? FarFetch automatically detects if an absolute path is used, and will override the baseURL.

await ff.get('https://notexample.com/posts');

Before/After Send Hook

You can use the built-in beforeSend() hook to do something before every request and the afterSend(response) one to do something after every request.

const ff = new FarFetch({
  beforeSend() {
    console.log('do this before every request');
  },
  afterSend(response) {
    console.log('do this before every request');
  },
});

You can also use any Init options from Fetch API as the return to add or override an option.

beforeSend() {
  // Use authorization header if token set in localStorage
  if (localStorage.getItem('token')) {
    return {
      headers: {
        'Content-Type': 'text/plain',
        Authorization: `Bearer ${localStorage.getItem('token')}`,
      },
    };
  }
}

Turn off Before/After Send Hook on Single Request

You might want to use the beforeSend() or afterSend(response) hook on nearly all requests, but turn it off certain ones.

await ff.get('http://example.com/', {
  globalBeforeSend: false,
  globalAfterSend: false,
});

Error Handling

Another annoyance of Fetch API is that it doesn't automatically throw an error on a failed request, and forces you to throw your own.

Fetch API

const data = { name: 'Bobby Big Boy', gender: 'Male', age: 5 };

try {
  const response = await fetch('https://example.com/people', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(data),
  });

  if(!response.ok) throw new Error('Server error.');
} catch {
  alert('Error adding person');
}

Thankfully you don't need to worry about this with FarFetch. With FarFetch, you can just append the noun to errorMsgNoun and it'll append to a default template, dependent on the CRUD type.

FarFetch

try {
  await ff.post('https://example.com/person', {
    data: { name: 'Bobby Big Boy', gender: 'Male', age: 5 },
    errorMsgNoun: 'person'
  });
} catch {}

Your global handler would then handle it as such:

const ff = new FarFetch({
  errorHandler({ error, userMessage, response }) {
    if(response.status === 401) { // Unauthorized
      router.push('/login'); // Go to login page if logged out
    }

    // Error message will be presented to the user in an alert
    alert(userMessage);
  },
});

If an error occurs, this will result in an alert with the following message:

Error adding person.

You might be wondering how this works behind the scenes. Here's the basic template of what going into the userMessage parameter property.

let action = '';

if (method === 'GET' || method === 'HEAD') {
  action = 'fetching';
} else if (method === 'POST') {
  action = 'adding';
} else if (method === 'PUT' || method === 'PATCH') {
  action = 'updating';
} else if (method === 'DELETE') {
  action = 'deleting';
}

const userMessage = `Error ${action} ${errorMsgNoun}`;

Modifying the Default Error Message Template

You can even override this default template with the errorMsgTemplate property, which accepts function.

const ff = new FarFetch({
  errorMsgTemplate: ({ method, errorMsgNoun }) => {
    let action = '';

    if (method === 'GET' || method === 'HEAD') {
      action = 'retrieving';
    } else if (method === 'POST') {
      action = 'posting';
    } else if (method === 'PUT' || method === 'PATCH') {
      action = 'changing';
    } else if (method === 'DELETE') {
      action = 'removing';
    }

    return `Error ${action} ${errorMsgNoun}.`;
  },
});

In case you couldn't tell by this contrived example, I merely used synonyms of the default template. However, this allows flexibility to tailor to custom requirements.

Overriding Default Error Message for Single Request

Sometimes you might just want to change the message for a unique request. You can accomplish this via the errorMsg property.

await ff.get('https://example.com/users', {
  errorMsg: 'Oh no! We are having trouble retrieving your friends!',
});

Catching Exceptions Manually

Using the global errorHandler(), along with errorMsgNoun or errorMsg should work fine in most cases, but sometimes you might need to handle multiple cases. You can easily achieve this by simply omitting both errorMsgNoun and errorMsg. FarFetch will then know not to run the global error handler. You can then can the errors in a try/catch. Take a register account example for instance.

async register(type) {
  try {
    const response = await ff.post(`http://127.0.0.1:3333/${type}`, {
      data: {
        email: this.email,
        password: this.password,
      },
    });

    const responseData = await response.json();

    localStorage.setItem('token', responseData.token);

    this.$router.push('/');
  } catch (e) {
    if (e instanceof FarFetchError) {
      let userMessage = '';

      const { response, error } = e;

      if (response.status === 409) { // Conflict
        userMessage = 'Email is already in system';
      } else if (response.status === 400) { // Validation failed
        const { field, validationMsg } = response.responseJSON;

        userMessage = `${field} is ${validationMsg}`;
      }
      
      ff.errorHandler({ error, response, userMessage });
    } else {
      userMessage = e.message;

      ff.errorHandler({ error, userMessage });
    }
  }
}

Each case his handled individually. You can then add the string to the global error handler you created on instantiation, with ff.errorHandler({ error, response, userMessage }).

Empty Try/Catch

It is required to use a try/catch on every request in FarFetch, in order to stop execution on an error. This isn't because there's anything unique about how this library does anything; the same recommendation would apply to any async request in JavaScript that relies on sequential steps occurring on success. FarFetch specifically throws an error to stop the further execution of code. Perhaps an example would help illustrate my point better.

Consider how a simple register account might work, like in the previous example. You make a request and if there aren't any issues, like email already taken or validation issues, you set the localStorage to the JWT and then route to the logged in page. The problem is that if you an exception isn't thrown, there's nothing to stop the script's execution, and it'll always set localStorage and try to route to the logged in route, even if the request failed.

API

Classes

FarFetch

CRUD class to simplify fetch API and uploading.

FarFetchError

FarFetch Error class.

Typedefs

RequestException : object

The Request exception object.

ResponsePlus : object

Request object plus responseJSON and responseText properties if correct header type.

RequestOptions : object

The request object options.

beforeSendCallbackobject | undefined

Callback for global after send hook.

afterSendCallback : function

Callback for global after send hook.

errorHandlerCallback : function

Callback for global error handler.

errorMsgTemplateCallbackstring

Callback for overriding default error message template.

FarFetch

CRUD class to simplify fetch API and uploading.

Kind: global class

new FarFetch([options])

Create FarFetch object.

Param Type Default Description
[options] object {} Set options.
[options.baseURL] string '' Base URL for each request.
[options.beforeSend] beforeSendCallback Function to do something before each fetch request. Can return object with RequestOptions to add or override options.
[options.afterSend] afterSendCallback Function to do something after each fetch request.
[options.errorHandler] errorHandlerCallback Global error handler.
[options.errorMsgTemplate] errorMsgTemplateCallback Function to modify the default error message template for errorMsgNoun.
[...options.RequestOptions] RequestOptions

Example

const ff = new FarFetch({
  beforeSend() {
    console.log('Doing something before every request');
  },
  afterSend(response) {
    console.log('Doing after before every request');
  },
  errorHandler({ error, userMessage, response }) {
    if(response.status === 401) { // Unauthorized
      router.push('/login');
    }

    alert(userMessage); // Error message from either errorMsg or errorMsgNoun will be used
  },
  headers: { 'Content-Type': 'application/json' },
});

farFetch.fetch(url, options) ⇒ Promise.<ResponsePlus>

Request function called on every CRUD function.

Kind: instance method of FarFetch
Throws:

Param Type Description
url string The URL.
options object
options.method 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' The CRUD method.
[...options.RequestOptions] RequestOptions

Example

await ff.fetch('https://my-website.com/users', {
 method: 'GET',
 data: { id: 23 },
 errorMsgNoun: 'users',
});

farFetch.get(url, [...options]) ⇒ Promise.<ResponsePlus>

GET fetch request.

Kind: instance method of FarFetch
Throws:

Param Type Description
url string The URL.
[...options] RequestOptions

Example

await ff.get('https://my-website.com/users', {
 data: { id: 23 },
 errorMsgNoun: 'users',
});

farFetch.post(url, [...options]) ⇒ Promise.<ResponsePlus>

POST fetch request. Will default to 'Content-Type': 'application/json' for the request header if FarFetch data option is provided.

Kind: instance method of FarFetch
Throws:

Param Type Description
url string The URL.
[...options] RequestOptions

Example

await ff.post('https://my-website.com/user/23', {
 data: { gender: 'male', age: 39 },
 errorMsgNoun: 'user',
});

farFetch.put(url, [...options]) ⇒ Promise.<ResponsePlus>

PUT fetch request. Will default to 'Content-Type': 'application/json' for the request header if FarFetch data option is provided.

Kind: instance method of FarFetch
Throws:

Param Type Description
url string The URL.
[...options] RequestOptions

Example

await ff.put('https://my-website.com/user/47', {
 data: { gender: 'female', age: 22 },
 errorMsgNoun: 'user',
});

farFetch.patch(url, [...options]) ⇒ Promise.<ResponsePlus>

PATCH fetch request. Will default to 'Content-Type': 'application/json' for the request header if FarFetch data option is provided.

Kind: instance method of FarFetch
Throws:

Param Type Description
url string The URL.
[...options] RequestOptions

Example

await ff.patch('https://my-website.com/user/91', {
 data: { age: 18 },
 errorMsgNoun: 'user',
});

farFetch.delete(url, [...options]) ⇒ Promise.<ResponsePlus>

DELETE fetch request.

Kind: instance method of FarFetch
Throws:

Param Type Description
url string The URL.
[...options] RequestOptions

Example

await ff.delete('https://my-website.com/user/107', {
 errorMsgNoun: 'user',
});

farFetch.head(url, [...options]) ⇒ Promise.<ResponsePlus>

HEAD fetch request.

Kind: instance method of FarFetch
Throws:

Param Type Description
url string The URL.
[...options] RequestOptions

Example

await ff.head('https://my-website.com/user/107');

FarFetchError ⇐ Error

FarFetch Error class.

Kind: global class
Extends: Error

new FarFetchError(message)

Param Type Description
message string | object.<string, *> Will be in the message property if a string or its own properties if object.

RequestException : object

The Request exception object.

Kind: global typedef
Properties

Name Type Description
error FarFetchError FarFetch error.
response ResponsePlus Fetch API response plus added properties for syntactic sugar.

ResponsePlus : object

Request object plus responseJSON and responseText properties if correct header type.

Kind: global typedef
Properties

Name Type Default Description
response Response Fetch API response Response object.
[response.responseJSON] object FarFetch added property that transforms the body to JSON for syntactic sugar if the same response header type.
[response.responseText] string null FarFetch added property that transforms the body to text for syntactic sugar if the same response header type.

RequestOptions : object

The request object options.

Kind: global typedef
Properties

Name Type Default Description
[data] object.<string, (string|number|null|boolean)> {} Data sent to server on request.
[files] File | Array.<File> | object.<string, File> | object.<string, Array.<File>> Files to upload to server. Will use file as key if literal and files[] if array; if object, will use properties as keys.
[errorMsgNoun] string '' Appended error message noun to global error handler.
[errorMsg] string '' Error message used to global error handler. Overrides errorMsgNoun
[globalBeforeSend] boolean true Will this specific request use the beforeSend() hook?
[globalAfterSend] boolean true Will this specific request use the afterSend() hook?
[defaultOptionsUsed] boolean true Will this specific request use the default options specified on instantiation or with return value of beforeSend()?
[...rest] object {} Init options from Fetch API.

beforeSendCallback ⇒ object | undefined

Callback for global after send hook.

Kind: global typedef
Returns: object | undefined - If return value is set, will deep merge it with options set in constructor.

afterSendCallback : function

Callback for global after send hook.

Kind: global typedef

Param Type Description
response ResponsePlus Request object plus responseJSON and responseText properties if correct header type.

errorHandlerCallback : function

Callback for global error handler.

Kind: global typedef

Param Type Description
[options] object
[options.error] FarFetchError | Error The FarFetchError option. Will throw regular error if needed.
[options.response] ResponsePlus Request object plus responseJSON and responseText properties if correct header type.
[options.userMessage] string The message given to the user.

errorMsgTemplateCallback ⇒ string

Callback for overriding default error message template.

Kind: global typedef
Returns: string - Full error message string.

Param Type Description
[options] object
[options.method] 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' The CRUD method.
[options.errorMsgNoun] string The error message noun.
You might also like...

Kurs-repo för kursen Webbserver och Databaser

Webbserver och databaser This repository is meant for CME students to access exercises and codealongs that happen throughout the course. I hope you wi

Jan 3, 2023

A tiny wrapper built around fetch with an intuitive syntax. :candy:

A tiny wrapper built around fetch with an intuitive syntax. :candy:

Wretch A tiny (~ 3Kb g-zipped) wrapper built around fetch with an intuitive syntax. f[ETCH] [WR]apper Wretch 1.7 is now live 🎉 ! Please check out the

Jan 3, 2023

An even simpler wrapper around native Fetch to strip boilerplate from your fetching code!

An even simpler wrapper around native Fetch to strip boilerplate from your fetching code!

Super lightweight (~450 bytes) wrapper to simplify native fetch calls using any HTTP method (existing or imagined). Features Fully typed/TypeScript su

Dec 28, 2022

Immutable persistent data collections for Javascript which increase efficiency and simplicity.

Immutable persistent data collections for Javascript which increase efficiency and simplicity.

Immutable collections for JavaScript Immutable data cannot be changed once created, leading to much simpler application development, no defensive copy

Dec 31, 2022

Immutable persistent data collections for Javascript which increase efficiency and simplicity.

Immutable persistent data collections for Javascript which increase efficiency and simplicity.

Immutable collections for JavaScript Immutable data cannot be changed once created, leading to much simpler application development, no defensive copy

Jan 7, 2023

Create Node.js app that is packed with best practices AND strive for simplicity

Create Node.js app that is packed with best practices AND strive for simplicity

Generate a Node.js app that is packed with best practices AND simplicty in mind. Based on our repo Node.js best practices (77,000 stars) ❣️ Alpha stag

Dec 31, 2022

Facile is an HTML form validator that is inspired by Laravel's validation style and is designed for simplicity of use.

Facile is an HTML form validator that is inspired by Laravel's validation style and is designed for simplicity of use.

Facile is an HTML form validator that is inspired by Laravel's validation style and is designed for simplicity of use.

Dec 26, 2022

Simple and Extensible Markdown Parser for Svelte, however its simplicity can be extended to any framework.

svelte-simple-markdown This is a fork of Simple-Markdown, modified to target Svelte, however due to separating the parsing and outputting steps, it ca

May 22, 2022

A lightweight @discord client mod focused on simplicity and performance.

Replugged Maintained fork of powercord - a lightweight @discord client mod focused on simplicity and performance. Installation/Uninstallation See the

Jan 9, 2023

A small, but powerful HTTP library for Deno & Deno Deploy, built for convenience and simplicity

A small, but powerful HTTP library for Deno & Deno Deploy, built for convenience and simplicity

Wren Wren is a small, but powerful HTTP library for Deno & Deno Deploy, built for convenience and simplicity. convenient aliases for HTTP responses au

Dec 12, 2022

Jest is a delightful JavaScript Testing Framework with a focus on simplicity.

Getting Started with Jest Jest is a delightful JavaScript Testing Framework with a focus on simplicity. Built With Javascript Linters Jest Live Demo N

Dec 20, 2022

Lightweight WebSocketServer wrapper lib using ws-wrapper to wrap connected WebSockets

ws-server-wrapper Lightweight WebSocketServer wrapper lib using ws-wrapper and ws to wrap connected WebSockets. The only dependency is ws-wrapper itse

May 9, 2022

🌳 Tiny & elegant JavaScript HTTP client based on the browser Fetch API

Huge thanks to for sponsoring me! Ky is a tiny and elegant HTTP client based on the browser Fetch API Ky targets modern browsers and Deno. For older b

Jan 2, 2023

Isomorphic WHATWG Fetch API, for Node & Browserify

isomorphic-fetch Fetch for node and Browserify. Built on top of GitHub's WHATWG Fetch polyfill. Warnings This adds fetch as a global so that its API i

Jan 2, 2023

A light-weight module that brings the Fetch API to Node.js

A light-weight module that brings the Fetch API to Node.js

A light-weight module that brings Fetch API to Node.js. Consider supporting us on our Open Collective: Motivation Features Difference from client-side

Jan 4, 2023

This simple project aims to connect to an API to fetch score data and display it on a LeaderBoard box, as well as provide the tool to submit a new score.

      This simple project aims to connect to an API to fetch score data and display it on a LeaderBoard box, as well as provide the tool to submit a new score.

Leader Board: Hit the API! This simple project aims to connect to an API to fetch score data and display it on a LeaderBoard box, as well as provide t

Apr 6, 2022

"Choose your Pokemon" is a Webpack project meant to fetch data from two different APIs: PokéAPI and Involvement API

"Choose your Pokemon" is a Webpack project meant to fetch data from two different APIs: PokéAPI and Involvement API. Here we display a list of 20 Pokemons for whom one can like, display more info, and comment; all based on the data from these two external resources.

Mar 31, 2022

A script for Obsidian's QuickAdd plugin, to fetch books data using Google Books API.

A script for Obsidian's QuickAdd plugin, to fetch books data using Google Books API.

Books script for Obsidian's Quickadd plugin Demo If this script helped you and you wish to contribute :) Description This script allows you to easily

Dec 31, 2022

API and CLI tool to fetch and query Chome DevTools heap snapshots.

Puppeteer Heap Snapshot Capture heap snapshots and query the snapshot for objects matching a set of properties. Read more about it in this blog post.

Jan 3, 2023
Comments
  • Pass url and current config to the beforeSend() callback

    Pass url and current config to the beforeSend() callback

    Similarly to what Axios does with request interceptors, it would be useful that the beforeSend() callback receives the called URL and the fetch config. For example, to inject HTTP headers depending on the fetched URL.

    opened by gbcreation 3
  • beforeSend global support async/await

    beforeSend global support async/await

    I am trying to use auth0 spa plugin and one of its methods to get the access-token to put in authorisation header is asynchronous (getTokenSilently). I would like to use that in beforeSend to setup global Authorisation header but far-fetch doesn't support async beforeSend. Any chance that this can be added?

    Axious has something similiar - see below.

    apiClient.interceptors.request.use(async (config) => {
        const token = await myApp.$auth.getTokenSilently();
        config.headers['Authorization'] = `Bearer ${token}`;
        return config;
    }, (error) => {
        return Promise.reject(error);
    });
    
    opened by alvins82 3
  • Change to responseData, instead of responseJSON, etc.

    Change to responseData, instead of responseJSON, etc.

    • Add defaultResponseType to constructor.
    • Add responseType to individual request.
    • Change README to account for change
    • Change testing to account for change
    opened by D-Marc1 0
Releases(v2.0.1)
  • v2.0.1(Jan 17, 2022)

    Removed

    • localBaseURL option removed.

    Fixed

    • Fix typo in README on array/object as value for key.
    • Fix typo in docs where it said to be using beforeSend() return instead of dynamicOptions().
    Source code(tar.gz)
    Source code(zip)
  • v2.0.0(Jan 16, 2022)

    Added

    • dynamicOptions() returns dynamic options instead of beforeSend(); accepts await.
    • localBaseURL option to automatically detect when working locally.
    • Missing testing.

    Changed

    • beforeSend() callback parameter now has the current URL and all the request options as object parameters.
    • beforeSend() return is not longer used for dynamic options, as a dedicated dynamicOptions() function is now used for that.
    • afterSend() and errorHandler accept await.

    Fixed

    • Minor typos in README and docs.
    Source code(tar.gz)
    Source code(zip)
  • v1.2.0-1(Oct 18, 2021)

  • v1.1.3(May 25, 2020)

  • v1.1.2(May 25, 2020)

  • v1.1.1(May 25, 2020)

  • v1.1.0(May 24, 2020)

  • v1.0.9(May 24, 2020)

  • v1.0.8(May 21, 2020)

  • v1.0.7(May 21, 2020)

    • Fix typos in docs 461b7db
    • Fix typos in README and in docs. Minor reorder. db69f70

    https://github.com/websitebeaver/far-fetch/compare/v1.0.6...v1.0.7

    Source code(tar.gz)
    Source code(zip)
  • v1.0.6(May 18, 2020)

  • v1.0.5(May 18, 2020)

  • v1.0.4(May 17, 2020)

  • v1.0.3(May 13, 2020)

Ts-api - This is a Typescript library facilitating usage of Localazy's API.

@localazy/ts-api This is a Typescript library facilitating usage of Localazy's API. To better understand this library, it is recommended to study the

Localazy 2 Jun 17, 2022
Bearer provides all of the tools to build, run and manage API integrations.

Bearer - The API Integration Framework Bearer provides all of the tools to build, run and manage API Learn more Archive Status Bearer JS has been arch

Bearer.sh 22 Oct 31, 2022
Optic documents and tests your API as you build it

Optic uses real traffic to document and test your APIs Language agnostic, works with any Rest API Optic observes development traffic and learns your A

Optic 1k Dec 31, 2022
REST API for muvi

muvi API REST API for muvi - a Chrome extension to download movies directly from a Google search. Run it locally npm i npm test How to contribute Help

null 6 Sep 19, 2021
Cuma mau bantu mereka yang kepengen bikin api sendiri

Source Codes - Zhirrr's API Api Features Check it yourself Here Cara Ganti ApiKey Gimana? Cara Mengganti Nya Cukup Gampang, Kalian Hanya Perlu Untuk M

zeeone 46 Jan 13, 2022
An API by Sujal Goel.

API ?? An API by Sujal Goel. Features ?? ?? Discord OAuth2 ✨ Simple and easy to use ?? Token based authentication for endpoints and much more! Contrib

Sujal Goel 4 Nov 7, 2021
API KBANK ( KBIZ )

Kbiz API Unofficial Kbiz's API. Examples ก่อนใช้งาน จำเป็นต้องลง axios ก่อน var kbizapi = require("./kbiz.class"); (async()=>{ var config = {

Think so. 9 Sep 7, 2022
A simple project to helping developer's to access open api's

OAS: OPEN APPLE STORE, has made this with the help of Apple Store item, this project which provide an additional choice to developer to interact with API.

Abhay Prajapati 8 Nov 19, 2022
Grupprojekt för kurserna 'Javascript med Ramverk' och 'Agil Utveckling'

JavaScript-med-Ramverk-Laboration-3 Grupprojektet för kurserna Javascript med Ramverk och Agil Utveckling. Utvecklingsguide För information om hur utv

Svante Jonsson IT-Högskolan 3 May 18, 2022
Hemsida för personer i Sverige som kan och vill erbjuda boende till människor på flykt

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

null 4 May 3, 2022