π Fetching data
Learning Objectives
So far we have displayed film data stored in our JavaScript code. But real applications fetch data from servers over the internet. We can restate our problem as follows:
Given an API that serves film data
When the page first loads
Then the page shouldfetch
and display the list of film data, including the film title, times and film certificate
π» Client side and π Server side APIs
We will use fetch()
, a
APIs are useful because they let us get information which we don’t ourselves know. The information may change over time, and we don’t need to update our application. When we ask for the information, the API will tell us the latest version.
We also don’t need to know how the API works in order to use it. It may be written in a different programming language. It may talk to other APIs we don’t know about. All we need to know is how to talk to it. This is called the interface.
Using fetch is simple. But we want to understand what is happening more completely. So let’s take ourselves on a journey through time.
ππΎ Unfurl to see the journey (we will explain this in little pieces)
graph TD fetch[(π fetch)] --> |sends a| Request{π€ Request} Request --> |has a latency| TimeProblem[ποΈ Time Problem] Request --> |to| ServerAPIs fetch --> |is a| ClientAPIs TimeProblem --> |caused by| SingleThread[𧡠Single thread] Callbacks{{πͺ Callbacks}} --> |run on| SingleThread SingleThread --> |handled by| EventLoop[π Event Loop] EventLoop --> |queues| Callbacks SingleThread --> |send tasks to| ClientAPIs SingleThread --> |handled by| Asynchrony TimeProblem --> |solved by| Asynchrony[ποΈ Asynchrony] Asynchrony --> |delivered with| Promise{{π€ Promises}} Asynchrony --> | delivered with | ClientAPIs Promise --> |resolve to a| Response{π€ Response} Promise --> |join the| EventLoop{{Event Loop π}} Promise --> |syntax| async{{πββοΈ async}} async --> |syntax| await{{π await}} await --> |resolves to| Response Response ---> |sequence with| then{{βοΈ then}} APIs((π§° APIs)) --> |live in your browser| ClientAPIs{π» Client side APIs} ClientAPIs --> |like| setTimeout[(β²οΈ setTimeout)] ClientAPIs --> |like| eventListener[(π¦»πΎ eventListener)] APIs --> |live on the internet| ServerAPIs{π Server side APIs} ServerAPIs --> |serve our| Data[(πΎ Data)] Data --> |as a| Response
π΅βπ« This is a lot to take in. Let’s break it down and make sense of it.
Step-through-prep workshop π
ποΈ Latency
Learning Objectives
graph LR fetch[(π fetch)] --> |sends a| Request{π€ Request} Request --> |has a latency| TimeProblem[ποΈ Time Problem]
Instead of already having our data, we are now sending a request over the network to another computer, and then waiting for that computer to send us a response back. Now that our data is going on a journey over a network, we introduce the problem of latency.
Latency is the time taken for a request to traverse the network.
π‘ Network latency is travel time.
Why is latency a problem? Because it means we need to wait for our data. But our program can only do one thing at a time - if we stopped our program to wait for data, then we wouldn’t be able to do anything else. We need to handle this time problem.
Programming often involves time problems, and latency is just one of them.
β³ Asynchrony : outside time
Learning Objectives
We can handle latency using
We have written a lot of JavaScript programs that execute sequentially. This means that each line of code is run in order, one after the other.
For example:
console.log("first");
console.log("second");
console.log("third");
Outputs:
first
second
third
Each line of code is run in order. This is synchronous execution. We do this because JavaScript is
When we call a function, the function will run to completion before the next line of code is executed. But what if we need to wait for something to happen? What if we need to wait for our data to arrive before we can show it? In this case, we can use asynchronous execution.
Event Loop
We have already used asynchronous execution. We have defined eventListener
s that listen for events to happen, then execute a callback function. But here’s a new idea: eventListeners are part of the Event API. They are not part of JavaScript! π€― This means you can’t use them in a Node REPL, but they are implemented in web browsers. The core of JavaScript is the same everywhere, but different contexts may add extra APIs.
When you set an eventListener you are really sending a call to a Web API and asking it do something for you.
const search = document.getElementById("search");
search.addEventListener("input", handleInput);
The callback handleInput
cannot run until the user types. With fetch
, the callback function cannot run until the data arrives. In both cases, we are waiting for something to happen before we can run our code.
We use a function as a way of wrapping up the code that needs to be run later on. This means we can tell the browser what to do when we’re done waiting.
ππ½ Visualise the Event Loop
π§ Recap our concept map
graph LR TimeProblem[ποΈ Time Problem] --> |caused by| SingleThread[𧡠Single thread] SingleThread --> |send tasks to| ClientAPIs TimeProblem --> |solved by| Asynchrony[ποΈ Asynchrony] Asynchrony --> | delivered with | ClientAPIs{π» Client APIs} ClientAPIs --> |like| setTimeout[(β²οΈ setTimeout)] ClientAPIs --> |like| eventListener[(π¦»πΎ eventListener)] ClientAPIs --> |like| fetch[(π fetch)]
πͺ Callbacks
Learning Objectives
Consider this visualisation of an asynchronous program:
ππ½ Code running out of order and off the thread
When we call setTimeout
we send a function call to a client side Web API. The code isn’t executing in our single thread any more, so we can run the next line. The countdown is happening, but it’s not happening in our thread.
When the time runs out, our Web API sends a message to our program to let us know. This is called an
Our call is back
With a pen and paper, draw a diagram of your mental model of the event loop.
Use your model to predict the order of logged numbers in the following code snippet:
setTimeout(function timeout() {
console.log("1");
}, 2000);
setTimeout(function timeout() {
console.log("2");
}, 500);
setTimeout(function timeout() {
console.log("3");
}, 0);
graph Callbacks{{πͺ Callbacks}} --> |run on| SingleThread[𧡠Single thread] SingleThread --> |handled by| EventLoop[π Event Loop] EventLoop --> |queues| Callbacks SingleThread --> |send tasks to| ClientAPIs{π» Client APIs} ClientAPIs --> | send| Callbacks
Did yours look different? There are many ways to visualise the event loop. Work on building your own mental model that helps you predict how code will run.
π Requesting from a server side API
Learning Objectives
So now we have these pieces of our giant concept map
- π€ we know that we can send a request using
fetch()
- π we know that
fetch
is a π» client side π§° Web API - ποΈ we know that sending π€ requests over a network takes time
- 𧡠we know that we should not stop our program to wait for data
- πͺ we know that we can use callbacks to manage events
But we still donβt know how to use fetch
to get data from a server side API. Letβs find this out now. In our filterFilms code, replace the films array with data fetched from a server.
// Begin with an empty state
const state = {
films: [],
};
// Data
const endpoint = "//curriculum.codeyourfuture.io/dummy-apis/films.json";
const fetchFilms = async () => {
const response = await fetch(endpoint);
return await response.json();
}; // our async function returns a Promise
fetchFilms().then((films) => {
render(filmContainer, films); // when
});
π fetch
returns a π«±πΏβπ«²π½ βPromise
; the π«±πΏβπ«²π½ Promise
fulfils itself with a π₯ response; the response contains our πΎ data.
We will dig into this syntax: Promises
, async
, await
, and then
in our next sprint and complete our concept map.
Define your product's MVP π
Learning Objectives
Preparation
Study this slide deck to get familiar with or refresh your knowledge of features and user stories.
Feel free to Google some other descriptions of this if the slide deck isnβt enough.
Introduction
Define your product's MVP
π― Goal: Define own productβs MVP (45 minutes)
Decide as a team on your productβs minimum viable product (MVP).Define the features needed for your product
π― Goal: List features for a product (45 minutes)
Make a list of the features that are needed for your MVP.