Week 06

Continue where we left off last week

What we're building:



Forms

Forms collect user information, making them essential for web applications. Understanding how to handle forms in JavaScript is crucial.

Here's a typical form in HTML:

<form>
  <label for="name">Name:</label>
  <input type="text" id="name" name="name" required/>

  <label for="email">Email:</label>
  <input type="email" id="email" name="email" required/>

  <label for="role">Role:</label>
  <select id="role" name="role" required>
    <option value="student">Student</option>
    <option value="instructor">Instructor</option>
    <option value="department_head">Department Head</option>
  </select>

  <button type="submit">Submit</button>
</form>

The most important thing to remember is the name attribute of the fields. When we turn the data from the form into JSON, the names will be the keys.

By default, clicking the Submit button sends the form data to the URL specified in the action attribute. If no action is set, the data is sent to the current page, causing a reload. To avoid this, we can use fetch to send data asynchronously. Here's how to prevent the default form behavior:

formElement.addEventListener("submit", function(event) {
    event.preventDefault();
})

Getting Form Data

First thing we need to do is to create a FormData object from the form element. It's a way to construct a set of key/value pairs representing form fields and their values. Read more here.

const data = new FormData(formElement)

Now we need to turn them into a JavaScript Object using Object.fromEntries(data) (read more here):

const objectData = Object.fromEntries(data)

Later on, when we need to send this object as a JSON document to a back-end server, we also need to turn it into a JSON string using JSON.stringify() (read more here):

JSON.stringify(objectData)

HTTP Verbs

HTTP verbs (or HTTP methods) define the type of action a client wants to perform on a server. The most commonly used HTTP verbs are:

  • GET – Retrieves data from the server.
  • POST – Sends new data to the server.
  • PUT – Updates existing data or creates it if it doesn’t exist.
  • PATCH – Partially updates existing data.
  • DELETE – Removes data from the server.

So far, we've been using the GET method for getting information from a back-end (e.g. the random fox or the blog server). When using fetch, you can specify the HTTP verb you want to use by passing an object as the second argument:

const response = await fetch("https://example.org/post", {
  method: "POST",
  // ...
})

When left unspecified, the default method is GET (what we've been doing so far). But now that we want to send form data to a back-end to be saved, we shouldn't use GET, but rather POST.

Different HTTP verbs have different ways of receiving data from a client (although you can sometimes bypass them, it's convention to use the proper method):

  • GET – Send data as query parameters in the URL (e.g., /users?id=123). It’s used for retrieving data and should not modify server state.
  • POST – Send data in the request body, typically as JSON or form data. It's used to create new resources.
  • PUT – Send data in the request body, replacing the entire resource. Used for full updates.
  • PATCH – Send data in the request body, but only updates specific fields instead of replacing the whole resource.
  • DELETE – Often doesn’t require a body, but if needed, data can be sent in the body or as query parameters.

Continuing our form example, here's how to send the form data in JSON format to a back-end using the POST method and request body in fetch:

const response = await fetch("http://backend.com", {
    method: "POST",
    headers: {
        "Content-Type": "application/json",
    },
    body: JSON.stringify(objectData),
});

The "Content-Type": "application/json" header tells the server that the request body is formatted as JSON.