NSWI142: Web Applications

11. JavaScript Client III.

Jáchym Bártík, KSI
jachym.bartik@matfyz.cuni.cz

Preliminaries

Please read this section at least one day prior to the seminar. This section outlines what you are expected to know, be able to do, or prepare in advance. Following these instructions will help you get the most out of the seminar and ensure smooth participation.

Preliminaries

Before the start of the practical, you should be able to:

  • Use JavaScript to create and manipulate with DOM in a browser.
  • Use JavaScript to listen for events.
  • Explain and use Promise and then/await.
  • Know how to use window.fetch function to perform HTTP GET request.

Preliminaries software

This slide applies to you only if you plan to use your own computer for the practical.

Before the start of the practical, make sure that:

  • You have a modern web browser.
  • An IDE with support for JavaScript would be nice.

Promise

Represents the eventual completion (then()) or failure (catch()) of an asynchronous operation. Promises can be chained. More about promises in the summer course.


      const promise = doSomethingAsynchronouslyAndReturnPromise();
      // Code immediately continues without waiting for the promise to resolve.

      promise.then(result => console.log("Success", result)); // Called once the promise is resolved.
      promise.then(result => logResult(result)); // We can attach multiple handlers.

      promise.catch(error => console.log("Failure", error));
      promise.catch(error => logError(error));
    

Promise chaining


      const promise1 = doSomethingAsynchronouslyAndReturnPromise();
      const promise2 = promise1.then(result => transformResult(result));
      const promise3 = promise2.then(result => transformResultAgain(result));

      promise3.then(result => console.log("Final result", result));
      promise3.catch(error => console.log("Failure", error));
    

Alternative implementation using chaining:


      doSomethingAsynchronouslyAndReturnPromise()
        .then(result => transformResult(result))
        .then(result => transformResultAgain(result))
        .then(result => console.log("Final result", result));
        .catch(error => console.log("Failure", error));
    

The then() method always returns a promise.
Its callback always receives a non-promise and may return either a promise or a non-promise.

Async/Await

We can use await when we are inside an async function.


      async function myFunction() {
        try {
          const result = await doSomethingAsynchronouslyAndReturnPromise();
          const nextResult = await transformResult(result);     // Similar to .then()
          const finalResult = transformResultAgain(nextResult); // Let's say this one is synchronous.
          console.log("Got the final result: " + finalResult);
        } catch (exception) { // Similar to .catch()
          console.log("Failure", error);
        }
      }
    

Async functions in practice

Async/Await meme.

Promise object API

A promise that fulfills when a button is pressed:


      const button = document.getElementById("my-button");
      const promise = new Promise((resolve, reject) => {
        button.addEventListener("click", () => {
          resolve();
        });
      });

      promise.then(() => {
        console.log("Button was pressed!");
      });
    

      async function waitForButtonPress() {
        ...
        await promise;
        console.log("Button was pressed!");
      }
    

Fetch API


      fetch(url)
        .then(response => response.json()) // Use .text() to get text content.
        .then(data => console.log("Got the data: ", data)) // Now we have the data.
        .catch(error => console.log("Can't fetch data", error));
    

Alternative implementation using async/await:


      try {
        const response = await fetch(url);
        const data = await response.json(); // .json() or .text() return a promise. We need to await it.
        console.log("Got the data:", data);
      } catch(error) {
        console.log("Can't fetch data", error);
      }
    

Cross-Origin Requests

Cross-origin network access (CORS) is using HTTP headers to control fetch. Below is an example of HTTP response headers allowing anyone to perform GET and POST.


      access-control-allow-methods: GET, OPTIONS
      access-control-allow-origin: *
    

CORS is implemented and enforced by browsers. Users are still able to execute request by other means!

Cross-origin resource sharing (CORS) is the SELinux of the Web. You really want to do the right thing but it only works when you: "Access-Control-Allow-Origin", "*"

      await fetch("https://mff.cuni.cz/");
      // See the Network tab.
    

Exercise: My first GET

Download api.html and implement the following: Fetch JSON from api.php and populate the table using the provided function. Since the API returns only some fields, keep the other fields empty.

Hints: Use console.log to debug what is happening.

Exercise: My first POST

Create website at webik in your public_html directory. Use JavaScript to POST JSON at json-processing.php. You need to post JSON of following shape:


    { "name": "Pavel", "position": "Teacher" }
  

Once you get the response, render it on your page.
You can specify additional options (body, method) for fetch using the second argument.

Exercise: My second GET

Continue with the previous exercise My first GET. For each item you fetched, follow its relative link property to get the full details. Update the table using the provided function.

  • Implement sequential fetching - one request after another.
  • Implement parallel fetching - send all requests at once and update the table as the responses arrive. Properly handle un-disabling the button when all requests finish.
  • How would you introduce delay between individual fetches?
  • How would you allow running only three requests in parallel?

Exercise: Your National Open Data Catalog

Download this page and resolve all TODOs. The objective is to have custom implementation of the catalog build upon GraphQL endpoint of Czech National Open Data Catalog.

Exercise: Submit HTML form

Download this page and resolve all TODOs.

The objective is to handle form submission using JavaScript.

Questions, ideas, or any other feedback?

Please feel free to use the anonymous feedback form.