CSE 154

Lecture 13: AJAX with JSON

Agenda

JSON warm up

AJAX fetch with JSON

AJAX fetch with text and JSON

CP 3 - JS with AJAX

Warm up

Worksheet (You may work with your neighbor)

For reference

Coming soon! Output Comparison Tool Version 2 and Version 3.... Iteration is the key!

Check for understanding

Talk with your neighbor

  • What is a AJAX? What does it stand for?
  • How is fetch related to AJAX?
  • What is a Promise?
  • What are the three states of a Promise
  • How are fetch and Promise related?

Poll

Review

We initiate a fetch of a URL

A fetch returns a Promise

Promises are good because...

  • They help deal with code that has an uncertain outcome
  • They separate the completion of the fetch request from the page logic
    • Lets us reuse the same logic and handle completion in different ways (Ajax logic vs page insertion, for example)
  • Chaining of Promises gives us a nice data flow, like down a pipe!

The Promise Pipeline

Visual description of the fetch pipeline

Output Comparison Tool version 2.0

How could we rewrite this site to use the organizational power of the JSON formatted file?

What do we have to change to the method that does the AJAX call?

function loadAssignments() {
  const url = "diff.txt";
  fetch(url)
    .then(checkStatus)
    .then(handleLoadAssignments)
    .catch(console.log);
}

JS

{
  "assignments": [
    {
      "assignmentName": "Hello Buggy",
      "numbered": false,
      "disabled": false,
      "expectedOutput": [
        {
          "outputName": "Hello Buggy",
          "outputFile": "HelloBuggy-expected-output.txt"
        }
      ]
    }
  ...
  ]
}

JSON

Partial solution

function loadAssignments() {
  const url = "diff.json";
  fetch(url)
    .then(checkStatus)
    .then(JSON.parse)
    .then(handleLoadAssignments)
    .catch(console.log);
}

function handleLoadAssignments(data) {
  let assignments = $("assignments");
  assignments.innerHTML = ""; // clear it out
  ...
  for (let i = 0; i < data.assignments.length; i++) {
    if (data.assignments[i].disabled === false) {
      let opt = document.createElement("option");
      opt.value = data.assignments[i].assignmentName;
      opt.innerText = data.assignments[i].assignmentName;
      assignments.appendChild(opt);
    }
  }
  assignments.disabled = false;
}

JS

Running solution here

Diff version 3.0

What if we wanted to have one text file, a "table of contents" of sorts, that listed all of the possible assignments for a quarter.

Each assignment then had it's OWN JSON file that contained the information about only that assignment.

Questions:

  • What are some of the benefits to splitting up the information in this way?
  • What are some of the drawbacks?
  • How will you fetch the data that you need now?

Partial solution - fetching the assignments

function loadAssignments() {
  const url = "assignments.txt";
  fetch(url)
  .then(checkStatus)
  .then(handleLoadAssignments)
  .catch(console.log);
}

function handleLoadAssignments(responseData) {
  let assignments = $("assignments");
  data = responseData.split("\n");
  assignments.innerHTML = ""; // clear it out
  ...
  for (let i = 0; i < data.length; i++) {
    loadSpecificAssignment(data[i], handleLoadOneAssignment);
  }
  assignments.disabled = false;
}

JS

Running solution here

Partial solution - fetching the output

// A neat trick to reuse the "callAJAX" pattern
function loadSpecificAssignment(assignment, handleResponse) { // pass in a function
  const url = assignment.replace(" ", "_") + ".json";
  fetch(url)
    .then(checkStatus)
    .then(JSON.parse)
    .then(handleResponse)  // use the function here
    .catch(console.log);
}
function handleLoadOneAssignment(data) {
  let assignments = $("assignments");
  if (data.disabled === false) {
    ...
    opt.value = data.assignmentName;
    let name = data.assignmentName;
    if ("randomSeed" in data) {
      name += " (random seed = " + data.randomSeed + ")";
    }
    opt.innerText = name;
    assignments.appendChild(opt);
  }
}

JS