WDD 330: Web Frontend Development II

W03 Individual Activity: Expand Inventory

Overview

Many of the changes you have already made were to prepare the site to be able to scale up to as many products as you would like. In this activity you will add products organized from four categories: Tents, Sleeping Bags, Backpacks, and Hammocks. You will need to change the index page to show the four categories, and then build a dynamic product listing page that will pull the products from an API, and display them.

Instructions

Complete the following assignment individually. Each student will write code for their own copy.

Core Requirements

Start the Task

  1. Visit the team's copy of the Trello board for the project.
  2. Add yourself to the Individual Activity W03: Expand inventory task.
  3. If no one else has done it yet, move it to 'Doing' list.
  4. Read the details of the card.
  5. Make sure to pull any changes from GitHub before proceeding.
  6. Create a new branch called yourinitials--individual3.

Refactor

  1. Create a new directory is src called product_listing.
  2. Add a new index.html file to that directory.
  3. Create a product-listing.js file in the js directory.
  4. Add basic HTML to the new index.html page such as the header, footer, styles, etc. You may just want to use src/index.html as a starting point. Then remove the unnecessary content including the banner and text.

    ✔ Adding a new page to the site requires that vite.config.js file be updated to let Vite know about it or the build will break.

  5. Move the JavaScript from the main.js that is responsible to render the list of products to the new product-listing.js file. (This is, in fact, most of the current main.js content.)
  6. Open up product_listing/index.html in the browser to make sure the tents are still rendered.

    You will need to fix some paths to get everything working correctly. For example, the new page will not be able to find the CSS file nor the new JS file you made until the file paths are fixed. Do not worry about fixing the image URLs yet. Those will change again anyway and you will fix those later.

  7. Display the four product categories images on the src/index.html page under the hero image.
    Screenshot of Product Categories
    Screenshot of Product Categories Display

    You can use your own icons or the svg images provided here:

  8. Link each of the category elements to product_listing/index.html.
    Make sure to pass the correct category as part of the URL (tents, backpacks, sleeping-bags, or hammocks).

    If you need a reminder of how to add a URL parameter to a link check out the template function in ProductList.mjs. It has an example of passing a parameter in the URL.

Environment Variables

This application will be changed to use an API server that will provide endpoints to access tasks like getting product information, logging in users, submitting orders, etc. During development, changes are made that do not need to show up in the production environment. The development server is a testing environment used during application development. The application can be changed without worrying about the live application on the production server which has the real real data that must be protected.

This separation is very common in development. This means however that you are going to have to change the URL that is being used depending on whether the code is running in a development environment or a production environment.

Environment variables are a way to store values that are specific to the environment the code is running in. For example, you could have a variable that stores the URL of the development server and another variable that stores the URL of the production server. Environment variables provide values that change automatically depending on where the code is running. Most of the time you create these in a file called .env (dotenv). You are using Vite as the build tool and it has the built in ability to work with these files. It will automatically look for a .env file and if it finds one it will make the variables defined therein available through a special global: import.meta.env.

Because Vite is for building frontend projects where all the code ends up in the browser, it gives us a way to control which of the environment variables become available in the client facing code. Any variable you want to use in the code you send out will need to be prefaced by VITE_ syntax.

  1. Open the .env.sample file in the src directory.
  2. Look for the variable named VITE_SERVER_URL.
  3. Note that the server URL is provided as VITE_SERVER_URL=https://wdd330-backend.onrender.com/.

    This server URL variable is not something you need to keep secret. It needs to be available in the code. It has the VITE_ prefix.

  4. 🗝️ Rename the .env.sample to .env using File->Save As. Vite will now see the file and use the variables in it.

    It is common practice to provide a sample with a different name to make it clear that it is not the real file.

You may be wondering why that file is called .env.sample. Environment variables often contain sensitive information in them and so it is common to not include those files in the Git repo for the project. If you take a look in the .gitignore file, you will see that .env files are already being ignored. Files named that way will never be tracked by Git.

The next question is how do environment variables get used in the production environment? That is addressed below.

When the code gets deployed to Netlify (the production environment) it will need to know the server URL it should use. Since the .env file will not be part of the repo it is set a different way.

Only one member of your teams needs to do the following maintenance.

  1. Log into Netlify and pull up the project.
  2. Navigate to the Site Settings->Environment Variables.
  3. Add a new variable.
  4. Enter VITE_SERVER_URL as the Key.
  5. Enter the server URL https://wdd330-backend.onrender.com/ as the Value.
  6. Be sure to Save the new variable.

Pulling from an API

Next, modify the code to pull the product data from an API instead of from the local JSON file. Because of the way it is structured, the code this should be fairly easy.

  1. Open up ProductData.mjs.
  2. In the constructor, a path was set for the products. That path was based off of the tents category and would later be used to pull the data. With the API the category in the DataSource is not needed. It will be passed in when needed which makes the DataSource more flexible.

    Add the following line to the top of the file:
    const baseURL = import.meta.env.VITE_SERVER_URL

    Notice the environment variable set in the .env file.

  3. Remove the category and path from the constructor.
  4. In the getData method, add a parameter of category and take this opportunity to change the fetch to use async/await. Change the getData function to look like this:
    async getData(category) {
      const response = await fetch(`${baseURL}products/search/${category} `);
      const data = await convertToJson(response);
      return data.Result;
    }

    Why return data.Result? It used to be simply data. The data sent back from the API is structured differently. You will have some other corrections to make because of this as well.

  5. Open productList.js for editing.
  6. Change the line in the init() method where data is retrieved. It should look like this after the changes:
    const list = await this.dataSource.getData(this.category);

You should now be seeing products listed if you click on one of the links, but there are two issues. The first is that no images are showing. The second is that all the links are showing the same list of products.

Pulling the Correct Products

You should be passing category in the URL to the product_listing page. You need to retrieve it from the parameter in product-listing.js. Then send it into the ProductList class. Remember that a method was created in the utils.mjs file that grabs parameters from a URL.

You have been moving a lot of things around. At this point your product-listing.js file should look something like this:

import ProductData from './ProductData.js';
import ProductList from './ProductList.js';
import { loadHeaderFooter, getParam } from './utils.mjs';

loadHeaderFooter();

const category = getParam('category');
// first create an instance of the ProductData class.
const dataSource = new ProductData();
// then get the element you want the product list to render in
const listElement = document.querySelector('.product-list');
// then create an instance of the ProductList class and send it the correct information.
const myList = new ProductList(category, dataSource, listElement);
// finally call the init method to show the products
myList.init();

Fix the Product Detail page

If you try and click on on of the products to see the details you will notice it is broken. You will need to make some of the same changes to product.js and productDetail.js that you made for the product listing.

There are a few places you need to check to do this.

Fix the images

The data structure of the products changed slightly. This is why the images are broken. Analyze the data coming back from the API and figure out how to fix this issue.

You can use the PrimaryMedium image for the productList, and PrimaryLarge for the productDetail for now.

Fix the title

Title of the product listings page currently says: Top Products. Add the category to that so that it looks something like this:
Top Products: Backpacks
If the backpacks category link was selected.

Example Solution

Do NOT open the solution example until you have worked through this activity as a team for at least one hour. At the end of the hour, if you are still struggling with some of the core requirements, you are welcome to view the example solution and use it to help you complete your own code. Even if you use the example code to help you, you are welcome to report that you finished the core requirements, if you code them up yourself. Remember, this is just an example.

Example Solution

The example solution can be found in the src directory: WDD 330 Sleep Outside Repository week3-Individual branch.

Finally

Wrap up this individual project work by finishing up your individual work and then coordinating with your team.

  1. Commit and push your changes.
  2. Meet with your team and discuss which team member's changes (branch) you would like to keep.
    Your team will only keep one.
  3. Submit a request for the branch that you decided to keep.
  4. Review the Pull Request, close it, and merge the branch back into the Main branch.
  5. Move the Trello card to the "Done" column.

Submission

Return to Canvas to report on your work.