JavaScript

In the previous chapter you already created a handler in your application returning an app.js file and also referenced that in your HTML code. Time to write the JavaScript code now.

The plan is to:

  • load the image data from the selected file
  • post this image data with the selected filter name to the backend
  • display the resulting file on the web page

Note: A lot of this JavaScript code is similar to the one from the Web tutorial. The important difference is in the last step where instead of calling into WebAssembly you send the image to a server.

✅ If there's a change on the file selector ("the user selected a file") or a new filter is selected you should send the image to the backend.

document.querySelector('input[type=file]').onchange = (evt) => {
  postImage();
};
document.querySelector('select').onchange = (evt) => {
  postImage();
};

✅ The above calls a new function.

async function postImage() {
  // (to be filled in)
}

✅ First grab the selected file and let the user know the application is working.

  let files = document.getElementById('files').files;
  if (!files.length) {
    return;
  }
  let file = files[0];
  let span = document.querySelector('span');
  span.innerText = "working...";

✅ Start by displaying the image. The JavaScript web API lets you turn the file object into an object URL that can be displayed.

  let imgEl = document.querySelector('img');
  imgEl.src = URL.createObjectURL(file);
  imgEl.width = "500";

✅ Next fetch the selected image filter name. If it's none you don't need to do any work!

  let span = document.querySelector('span');
  span.innerText = "working...";

  let imgEl = document.querySelector('img');
  imgEl.src = URL.createObjectURL(file);

✅ Reading the file to then submit it requires to read it and turn it into an array buffer first. That's available directly on the file object you already have.

  let img = await file.arrayBuffer();

✅ Now you can create a POST request to the /image API endpoint using the fetch API, using the image data as the body.

  let url = `/image?filter=${filter}`;
  let response = await fetch(url, {
    method: "POST",
    body: img,
  });

  if (!response.ok) {
    throw new Error(`HTTP error! Status: ${response.status}`);
  }

✅ The response can be turned back into an object URL, that you can then display again as before.

  let blob = await response.blob();
  imgEl.src = URL.createObjectURL(blob);
  span.innerText = "done.";

And that's it for the frontend. Next you can run the full application locally.