NUS Hackers Wiki
NUS Hackers Wiki
  • NUS Hackers Wiki
  • Hackerschool
    • Virtual Machines and Linux
    • Beginners' Guide to the Terminal
      • Introduction to the Terminal
      • Modern Shell Tools
      • Shell Scripting
      • Real World Scripting
      • Resources
    • Self-Hosting: Three Easy Pieces
      • 1. Setting up your server
      • 2. Running Services
      • 3. Monitoring your server
    • Vim
    • Introduction to Zig
      • Language Basics
      • Error Handling
      • Memory Management
      • Working with C
      • Exploring comptime
    • CI/CD with Github Actions
      • Background
      • Basics of Github Actions
        • Target workflow
        • Running unit tests
        • Linting code
        • Deploying to Github Pages
      • Advanced use cases
        • Pollers
        • Github script
        • Executing third-party scripts
        • Reusable workflows
      • Cookbook
    • Lightning Git
      • Git Concepts
      • Getting Started with Git
      • Making your first commit
      • Branching
      • Merge Conflicts
      • Integrating remote repositories
      • Collaborative Workflows
      • Commit Manipulation and Reflog
      • Interactive rebasing
      • filter-repo
  • Orbital
    • JavaScript
      • Browser Developer Tools
      • Getting Started
      • Datatypes
      • Operators and Operations
      • Loops and Conditions
      • Functions
      • Strings
      • Arrays
      • HTML
        • Getting Started
        • Tag Attributes
        • HTML Forms
        • Browser Inspector
      • CSS
        • Selectors
        • Colors in CSS
        • Measurements in CSS
        • The Box Model
        • Adding Styles - Part 1
        • Adding Styles - Part 2
      • Working with the DOM
        • Querying the DOM - Selectors
        • Querying the DOM - Element Attributes
        • Querying the DOM - Element Styles
        • Events with JS and HTML
        • Exercise: Click Counter
        • Editing the DOM
        • Fetch Requests
        • Exercise: The NUSMods API
    • React
      • Setup
      • State
    • React Native
      • Setup
      • Intro to JSX
      • Basic Syntax
      • Handling UI
      • Props
      • State Management
    • Git
      • Setup
      • Command Glossary
      • Fundamental Concepts
        • Getting Started
        • Integrating Remote Repositories
        • Branching
        • Merge Conflicts
      • Collaborative Workflows
        • Fork and PR Workflow
        • Branch and PR Workflow
      • Advanced Concepts
        • Ignoring Files
        • Commit Message Conventions
        • Github Collaborators
        • CI/CD with Github Actions
        • Advanced Git Commands
      • FAQ
    • Telegram Bot
      • Creating a TeleBot
      • API Calls
      • Telebot Basics
      • Integrating API's
    • Relational Database
      • Database Overview
      • Database Design
      • Entity Relationship Diagram
      • SQL Basics & PostgreSQL
    • TypeScript
      • Types and Interfaces
      • Utility Types
      • Typing Component Props, Events, and Hooks
      • Why You Should Avoid Using any (and What to Do Instead)
      • TypeScript Tricks You’ll Use All the Time in React
Powered by GitBook
On this page
  • Syntax
  • The response
  • The options
  • Next steps
Edit on GitHub
Export as PDF
  1. Orbital
  2. JavaScript
  3. Working with the DOM

Fetch Requests

PreviousEditing the DOMNextExercise: The NUSMods API

Last updated 12 months ago

Fetch requests are a way to send HTTP requests to a server directly from a page using JavaScript. The advantage of using fetch requests over, say, reloading the page are that

  1. The contents of the page do not need to be reloaded each time the request is made

  2. The request takes a little less time to get processed compared to sending server-to-server requests from the backend.

  3. Allows content to be loaded "optionally" - content is not loaded on the page until it is specifically requested by the user, so pages have less content and are rendered faster.

Syntax

Fetch requests follow this syntax:

fetch(resource, options)
  • resource is the server (or resource) that the request is being sent to. It is a string with the URL.

  • options contain some custom settings for the request. More details later

They return a - in other words, they return an asynchronous wrapper for the response from the server.

For those of you who have taken CS2030/S, Promises in JavaScript are like CompletableFutures in Java.

This promise can be processed using the .then method, which takes in a unary function. This function is applied on the response recieved from the server.

fetch(resource, options)
.then(processResponse);

The response

The response from a fetch request is a JSON object with parameters like status and protocol and body. Of these, the status and body parameters are the most useful for now.

  • 200 OK - all good

  • 404 NOT FOUND - the url/resource was not found on the server side

  • 500 Internal Server Error - the server ran into an error when trying to process the request

response.body is an encoded object that contains the body of the response. Note that failed requests have null as the value for the body property for their response objects. To decode the body into readable JSON that can be processed by your JS code, use the method response.json().

You could imagine using the status property in this way:

fetch("somedomain.com/some-route/", someData)
.then(response => {
    if (response.status === 200) {
        let data = response.json(); // get the data
        // do something with the data
    } else {
        // show the user some error message
        alert(`Error: ${response.status}`);
    }
})

This status-checking and body-retrieval is often chained into 2 different promises using two sequential thens:

fetch("somedomain.com/some-route/", someData)
.then(response => response.status === 200 ? response.json() : response.status)
.then(data => {
    if (typeof(data) === "number") {
        // show the user some error message
        alert(`Error: ${response.status}`);
    } else {
        // process the data
    }
})

Let's walk through it step by step:

  1. fetch("somedomain.com/some-route/", someData) - this line performs the fetch request and returns the response wrapped in a promise

  2. .then(response => response.status === 200 ? response.json() : response.status) - here, we check the response status code to see if the request was successful.

    • If the response was successful (i.e. response.status === 200) then we return the body of the response using response.json()

    • If the response was not successful, we return the status code of the response so it can be shown to the user

  3. .then(data => {...}) - this section of the code takes the data returned after processing the response

    • If the data returned is a number (i.e. typeof(data) === "number") then this means that the response status code was returned by the previous function, so there was an error, so we tell the user as such

    • Otherwise process the data as normal

Note that you may want to add more intermediary conditions and process different response codes differently, but the general form of a fetch request is as above.

The options

Note that the fetch function takes in two parameters: the resource, and the options.

options is a JSON object that contains any custom settings that you may want to apply to the request. This includes header data, type of content being sent (if any), the content itself, and others. If any settings are ommitted, then the browser plugs in the default values for each setting. Below is an example of the options object, filled with default values for each setting (not all possible settings are shown).

let options = {
    method: "GET",
    mode: "cors",
    cache: "default",
    credentials: "same-origin",
    redirect: "follow",
    headers: {
        "Content-Type": "application/json",
        "Access-Control-Allow-Origin": "*"
    },
    body: JSON.stringify(someJSONData)
}

Let's look at each setting:

  1. headers - this is a JSON object that contains the headers for the request. The sample shows two header settings:

  1. body - this setting specifies the body of the request (i.e. some data that needs to be processed by the resource server). Note that this must be a string; JSON.stringify allows us to represent a JSON object with the request body as a string. Note also that a body CANNOT be present for a GET request.

Next steps

Next, we'll write our own fetch request to the NUSMods API.

response.status is an integer representing the HTTP Response Code returned by the server. The full list of response code can be found , but a few common ones are below:

method - this setting specifies the request method. There are 4 commonly used methods(GET, POST, PUT and DELETE), and each are used in different situations. More details

mode - what resource sharing mode should be allowed. "cors" stands for "Cross-Origin Resource Sharing", and this mode allows sharing resources across origins. The other options are "no-cors" and "same-origin". More details

cache - how the request interacts with the browser's cache. Some different options are "no-cache", "no-store", "reload", and "only-if-cached". These options are explained

credentials - this specifies whether or not the user should send/receive cookies from the resource. The two other options are "omit" (never send/receive cookies) and "include" (always send/receive cookies). More details

redirect - this specifies how to handle if the resource redirects our request elsewhere. Some other options are "error" and "manual". More details

"Content-Type" - this header specifies the type of content being requested. It is in the format "type/subtype" and some examples are "image/png" (a png image), "text/plain" (plain text), or "multipart/form-data" (multiple parts of form data). The full list of options can be found .

"Access-Control-Allow-Origin" - this header indicates whether the response can be shared with requesting code from the given origin. This could be "*", so all origins can have access to the response, or "<origin>" where <origin> is a domain/IP address. More details

There are many more headers that can be assigned, and they are all listed .

The are a very very useful resource for understanding HTTP requests and responses, as well as frontend web development with JavaScript.

"Promise"
here
here
here
here
here
here
here
here
here
Mozilla Developer Network web docs