- Lab
- Core Tech
![Labs Labs](/etc.clientlibs/ps/clientlibs/clientlib-site/resources/images/labs/lab-icon.png)
Guided: APIs in JavaScript
In this lab, you'll develop key components of a web application that allows users to explore a collection of movies and manage their personal watchlist. This lab emphasizes crucial web development concepts such as API interactions and asynchronous JavaScript.
![Labs Labs](/etc.clientlibs/ps/clientlibs/clientlib-site/resources/images/labs/lab-icon.png)
Path Info
Table of Contents
-
Challenge
Introduction
In this Code Lab, you are provided with a pre-built Movie-Thon web application. This interactive application helps users explore movies and manage a personal watchlist through dynamic user interactions. Your goal is to implement the core functionalities using JavaScript to handle user inputs and interact with a backend API.
Tasks can be validated by clicking on the validate buttons next to them. If you are stuck or would like to compare solutions, a
solution
directory has been provided for you as well.Application Features:
- Homepage Display of Movies: Upon launching the app, users see a list of movies with details and an option to add them to a watchlist.
- Dynamic Watchlist Management: Users can add movies to a watchlist, which they can view and refresh at any time to see the latest additions.
How the Application Functions:
- The homepage displays a list of popular movies.
- By clicking on Add to Watch List next to each movie, the movie is saved to the user's personal watchlist, which they can view at any time.
- Each entry in the watchlist includes a Remove button.
- Any changes (additions or removals) are immediately reflected in the user interface.
- The front end interacts with a backend API where the data for movies is managed.
You will work within the following files:
Within the
src
directory, you will find:loader.js
: Includes functions and logic for loading the movies from the backend APIs and logic for removing the movies from the list.script.js
: Includes skeleton functions for adding to the watchlist and loading the watchlist. This is the file where you will write the code.style.css
: Provides basic styling for the movie list and interactive elements.
Within the
public
directory, you will find:index.html
: Contains the layout with a list display area for movies and a separate section for the watchlist.
Server and Backend Details:
Since this lab focuses on working with APIs, the server-side code plays a crucial role in managing and serving data. However, it will be pre-written and hidden from you to allow you to focus on front-end development.
Server Code:
The server is built using Express.js, a popular web framework for Node.js. It uses middleware like
cors
to handle cross-origin requests, ensuring the frontend can safely interact with the backend without running into cross-origin issues.Starting the Server
You need to start the server by running the command below in the Terminal:
node server/server.js
This will start the server along with API's on port 3000.
Head over to the Web Browser tab and use the Open in new browser tab icon to try out the application!
Exposed Server Endpoints:
The server exposes the following endpoints that you will interact with through your front-end code:
-
GET /api/watchlist:
- Method: GET
- Description: Returns the movies that exist in the watchlist.
-
POST /api/watchlist:
- Method: POST
- Description: Updates the watchlist with new data sent from the client.
Excited? Time to dive in!
-
Challenge
Implementing `fetchWatchList` Function
First, you need to implement the functionality to fetch the watchlist from the sever. For this, you will make use of
fetch()
andawait
.fetch()
provides a modern and versatile way to make HTTP requests to servers from web browsers. It returns aPromise
that resolves to theResponse
object representing the response to the request.The
await
keyword is used to pause the execution of anasync
function until aPromise
is resolved. It can only be used inside anasync
function. When used, it allows you to write asynchronous code in a synchronous manner, making it easier to read and maintain.When combined,
fetch
andawait
provide a powerful and easy-to-use approach for making HTTP requests and handling the responses in a readable and maintainable way. Usingawait
withfetch
allows you to wait for the server's response before proceeding with further operations, making your code cleaner and more efficient.Example Usage:
async function fetchData() { try { const response = await fetch('http://example.com/api/data'); const data = await response.json(); console.log(data); } catch (error) { console.error('Error:', error); } } fetchData(); ``` Once you have the response object, you need to ensure that any issues with the network request or server response are caught. This will allow you to handle errors gracefully and provide feedback to the user if necessary. The `response` object has `ok` property which is a Boolean and it indicates whether the HTTP request was successful. It returns `true` if the response status code is in the range 200-299, which signifies a successful request. If the status code falls outside this range, `ok` will be `false`, indicating a failure in the request. By verifying `response.ok`, you can determine if the request was successful and take appropriate action if it was not. ### Example: ```javascript if (response.ok) { // Request was successful } else { // Request failed } ``` When making HTTP requests, the response from the server often contains data that needs to be parsed. The `json()` method on the response object is used to parse the response body as JSON. Since `json()` returns a `Promise`, you should use `await` to handle its asynchronous nature. Remember, using a `try-catch` block allows you to handle errors gracefully in asynchronous code. The `try` block lets you define a block of code to be tested for errors while it is being executed, and the `catch` block lets you handle the error. - **`try` Block**: Contains the code that may throw an error. - **`catch` Block**: Contains the code that handles any error thrown by the `try` block. **Example Usage:** ```javascript try { const response = await fetch('http://example.com/api/data'); if (!response.ok) { throw new Error(`HTTP error! Status: ${response.status}`); } const data = await response.json(); return data; } catch (error) { console.error('Error:', error); }
-
Challenge
Implementing `addToWatchList` Function
So far, you have implemented the
fetchWatchList
function which will help you fetch the movies watchlist from the server. Now, you need to start working onaddToWatchList
function, which exists insrc/script.js
and will help you add movies to watchlist.The
addToWatchList
function is designed to add a new movie to the watchlist and update the server with the new watchlist. It accepts a movie object that's supposed to be added into watchlist as its argument. The function is using theasync
keyword and is marked as asynchronous because it involves network operations that need to be handled asynchronously to avoid blocking the main thread. Remember, when working with arrays, there will be scenarios where you will need to check if a certain element is present. TheArray.prototype.some()
method is useful for this purpose. It tests whether at least one element in the array passes the test implemented by the provided function. You have themovie
that needs to be added to watchlist as the function argument and list of movies present in watchlist as an array namedmovies
. You need to add a new movie to the watchlist array if it is not already present. To add a new element to an array, you can use theArray.prototype.push()
method. This method adds one or more elements to the end of an array and returns the new length of the array.Example Usage:
let array = [1, 2, 3]; array.push(4); console.log(array); // [1, 2, 3, 4] ``` To send data to a server, you can use the `fetch` function with the `POST` method. This involves configuring the request with the appropriate HTTP method, headers, and body. The `Content-Type` header is set to `application/json` to indicate that the request body contains JSON data. The `body` property is used to send the data, which should be a JSON string. - **`POST` Method**: Used to send data to the server. - **Headers**: Configure the `Content-Type` to `application/json`. - **Body**: The data to be sent, typically a JSON string. **Example Usage:** ```javascript await fetch('http://example.com/api/data', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(data) }); ``` After successfully updating the watchlist on the server, it is important to refresh the watchlist displayed on the page to reflect the latest changes. This can be done by calling the `loadWatchList` function, which retrieves the updated watchlist from the server and updates the user interface accordingly.
-
Challenge
Implementing `loadWatchList` Function
Now that you have implemented
addToWatchList
andfetchWatchList
function, it is time to implementloadWatchList
function that will display the watchlist from the server each time the page is loaded or updated.You need to remember, to interact with the elements in the DOM (Document Object Model), you can use the
document.getElementById
method. This method returns a reference to the element by its ID, allowing you to manipulate it programmatically. Remember, when updating the contents of a DOM element, it is often necessary to clear any existing content to avoid duplication or outdated information. This can be done by setting theinnerHTML
property of the element to an empty string. This property allows you to get or set the HTML content inside an element. By setting it to an empty string, you remove all child elements and text within the element.As a next step, you have to make sure to clear the inner HTML of the
watchlist
element to ensure that the list is refreshed without duplicating any content. TheforEach
method in JavaScript is used to execute a provided function once for each array element. This method is particularly useful for performing operations on each item in an array. Now that you have cleared the watchlist, you need to work on displaying it back again, you will iterate over themovies
array to dynamically generate and display each movie in the watchlist.Example Usage of forEach:
const array = [1, 2, 3]; array.forEach(element => { console.log(element); }); ``` Remember to dynamically add content to the DOM, you can create new elements and set their properties using JavaScript. The `document.createElement` method is used to create a new element, and the `textContent` property is used to set the text content of an element. Also, here is the response from the GET request to `/api/watchlist`. You are making this call in `fetchWatchList()` function and a call to that function has provided the following structure for movies in the variable named `movies`: ```json [ { "id": 6, "title": "The Dark Knight", "director": "Christopher Nolan", "cast": [ "Christian Bale", "Heath Ledger" ], "runtime": "152 minutes", "genre": [ "Action", "Crime", "Drama" ] } ] ``` Once you have the movie information displayed, you need to work on the `button` that would be used to remove a movie from the watchlist Event handlers are functions that are called when a specific event occurs. You have a `button` on the interface but there is no interactivity there. To make it interactive, you will attach an `onclick` event handler to a `button` element. The handler function will call `removeFromWatchList` with the movie's ID to handle the removal logic. This helps in making the interface interactive and responsive to user actions. You now have the `listItem` and the `button` created. But they are not being rendered on the interface. You need to add them to the interface with the help of `DOM`. You are done! Head over to the **Web Browser** tab and use the **Open in new browser tab** icon to try out the application! See the movies being fetched. Click on the **Add to Watch List** button next to each movie, the movie is saved to the watchlist. Try clicking on **Remove** button in the watchlist to get the movie removed.
What's a lab?
Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.
Provided environment for hands-on practice
We will provide the credentials and environment necessary for you to practice right within your browser.
Guided walkthrough
Follow along with the author’s guided walkthrough and build something new in your provided environment!
Did you know?
On average, you retain 75% more of your learning if you get time for practice.