Code Challenge Tutorial
Tags: beginners, javascript, frontend, tutorial
Published: 2023-04-01 23:37:47

   Hi, my name is Josh! Are you about to take your first **Coding-Challenge**, or did you just fail your first Challenge? Well then you are in luck. This tutorial will be a step by step guide to pass your deliverables. I will cover base deliverables. This will be great if you just started phase-1 for Software-Engineering program with FlatIron School.
  
 So First we are gonna start with a github link, with special thanks to Flatiron, for the resource. We will be using an Instructor's created one. This challenge is called **Calexico**. Here is the link so you can follow along:[The Challenge](https://github.com/bdenney/phase-1-calexico)
And here is a photo of the Deliverables:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/s31gkdbu0c3pqikhi6gh.png)
So to begin, the first thing you will want to do is check the Html file. If your script tag where you call the .js file, is on the top of the page that you have a defer. It should look like this:

![Line 4 of html](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ye47a31ibx305l4m9dvs.png) 

This is very important because when we start using DOM elements, and manipulating them, we will need access to all the HTML. So if we do not defer the page will load the .js file before loading the entire .HTML file which can be problematic. Now that we have done that we can move to the next step. 

Alright this is where you will look at your preview and run 
`json-server --watch db.json`
in your terminal, make sure you are in the proper folder. This will give us access to the back end or server, in this case db.json. Then we are going to grab the URL that we will need which in this case is http://localhost:3000/menu
we will assign it to a variable 

```
const menuUrl = "http://localhost:3000/menu"
```
This will be the first line in your .js file

Now move on to the next step. Open the preview file and find all the DOM Elements you will need to pass the base Deliverables. This is first seen in the second Deliverable/Challenge. Do not fret, I know we have not done the first yet, we will get there.
 

**Challenge #2
When the page loads, display the first menu item. You should set the _image, name, description, and price_. All the correct elements to set are located in the #dish section element.**
 
So from this we see that we will need the image, name, description, and price elements from the HTML. So this is where we will start coding the next few lines. I like to comment what each section is doing so I will put a //Dom Selectors then list every Dom element we will need. 
Which looks like this 
We also should look at the other deliverables to see if we will need any more then just those.
Which there are: 

**Challenge #1
Fetch all the menu items from http://localhost:3000/menu. For each menu item create a span element that contains the name of the menu item, and add it to the _#menu-items div_.
Challenge #3
When the _user clicks on the menu items on the left_, they should see all the details for that specific menu item.
Challenge #4
The user should be able to add the menu items to their cart. When the user presses the _'Add to Cart' button_, that number should be added to however many are currently in the cart.**

So I put in italics what the other Dom elements we will need. Next up is to grab these elements and assign them to variables like so: 


```
//Dom selectors
const menuDiv = document.getElementById("menu-items")
const menuDetails = document.getElementById("dish")
const menuImage = document.getElementById("dish-image")
const menuName = document.getElementById("dish-name")
const menuDescription = document.getElementById("dish-description")
const menuPrice = document.getElementById("dish-price")
const menuCart = document.getElementById("number-in-cart")
const menuForm = document.getElementById("cart-form")
const menuCartAmount =  document.getElementById("cart-amount")
const currentCart = {}
```
Now that we have this we can move forward to our next step. We will add a new comment for our block of code called //Fecthes. In this we have two options. we can either have the fetch in an arrow function that will need to be initalized at the bottom of the page which would look like so 

```
//fetches
const fetchAll = () =>{
    fetch(menuUrl)
}
//init
const init = () =>{
    fetchAll()
  }
  init()
```
This init function will load our fetch on      
page-load. Now this fetch will not do anything yet because we are not done. The fetch will be what we utilize to grab all the information we will need from the Server. The fetch provides the front end access to it. So you will first write fetch() and in the parameter is where you will call the URL. Now remember that is the first line we wrote so in this case we can just put that variable in fetch(menuUrl). Next step is to tell js what we are doing with this information in two .then s. the completed code looks like this. 

```
const fetchAll = () =>{
    fetch(menuUrl)
    .then((response) => response.json())
    .then (menuArr => {
      console.log(menuArr)
      menuArr.forEach(menuObj => {
          renderMenuNames(menuObj)
      });
   renderMenuDetails(menuArr[0])
  });
}
```
The first .then returns a promise, the second .then grabs the array then assigns it to an arrow function in which we console log the array to make sure we are getting the information we want. The next line is where we do a forEach statement in that we attach to the array of objects we just grabbed called _menuArr_. Then in the parameter we state for each object or in this case _menuObj_ arrow function then a call back function with the parameter of that object. Dont worry about the renderDetails line underneath the forEach function for now, I will come back to it.  Now is time for the next section, rendering the fetch onto the page. 

## Deliverable 1
_
Challenge #1
Fetch all the menu items from http://localhost:3000/menu. For each menu item create a span element that contains the name of the menu item, and add it to the #menu-items div._

  So it's easy to read we named my call-back function **renderMenuNames**. Because this is the first deliverable its asking for. So we now define renderMenuNames and assign it to an arrow function, with the parameter **menuObj**. Within the arrow function the first deliverable asks to create a span tag. So that will be the first line, then we will want to set that new tags textContent to equar our menu objects name. So we look at the Json to figure out what the name is put in. In this case it is just name, so menuObj.name will assign the span tags text to equal each of the array of objects name. The next step is to append it to the div. We already assigned this element to the variable menuDiv, so we append the new spanTag we created to the that Div. The code should look like this 

_**-NOTE YOU WILL NEED TO ADD THE CALL BACK FUNCTION renderMenuDetails WITH MENUOBJ TO THE BOTTOM OF YOUR renderMenuNames FUNCTION WITH THE ARGUMENT OF MENU OBJ IN ORDER FOR THE SCOPE TO WORK IF YOU HAVE NOT DONE DELIVERABLE 3 YET.**_
```
const renderMenuNames = (menuObj) => {
    const spanTag = document.createElement("span")
    spanTag.textContent = menuObj.name
    menuDiv.append(spanTag)
    renderMenuDetails(menuObj)
}
```
When you look at the page on the browser it should now look like this 

![deliverable One](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ty6q59n6h3xapc5a897x.png)

Congratulations we have now passed the first deliverable.

## Deliverable 2

_Challenge #2
When the page loads, display the first menu item. You should set the image, name, description, and price. All the correct elements to set are located in the #dish section element_.

  Now we will define that function mentioned in the fetch renderMenuDetails. This function will be an arrow function just like the previous one in which we take in the paramater menuObj, and then assign those Dom selectors we made to equal the servers details just like the name. So that line in the fetch is how we accomplish the first part of the second deliverable. Underneath the forEach function but still within the fetch function the line is saying call this function renderMenuDetails and set the parameter as menuArr and then grab the first obj in that array and load it on page load.
`renderMenuDetails(menuArr[0])`

_**-NOTE YOU WILL NEED TO ADD THE CALL BACK FUNCTION WITH MENUOBJ TO THE BOTTOM OF YOUR renderMenuNames FUNCTION WITH THE ARGUMENT OF MENU OBJ IN ORDER FOR THE SCOPE TO WORK IF YOU HAVE NOT DONE DELIVERABLE 3 YET.**_
  So now that we have that passing, next thing to do is finish writing that function out. So you will want to use the variables we assigned in the Dom Selectors for the Image, Name, Description, Price, and Cart. I know the cart is not listed in the second deliverable but it will make sense as we go along. Besides the image all the other selectors will be .textContent for the image you will use .src. Then you will assign each of these to the menuObj.[whatever the json pathway for that is]
When you finish it should look like this:
--note: I added the string of "$" + the menuObj.price just to be more aesthetically pleasing, it is not necessary to pass the deliverable.

```
const renderMenuDetails = (menuObj) => {
    menuImage.src = menuObj.image
    menuName.textContent = menuObj.name
    menuDescription.textContent = menuObj.description
    menuPrice.textContent = '$' + menuObj.price
    menuCart.textContent = menuObj.number_in_bag
  };
```
Which your webpage should now look like this. 

![1 & 2 Done!](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/at5sd9tkk02ysg0ue27x.png)

Congratulations the first two deliverables are now complete. 

## Deliverable 3

_Challenge #3
When the user clicks on the menu items on the left, they should see all the details for that specific menu item._

Time to move to deliverable 3. So this one is easy no new function needed, in fact we will be going back and writing this step in your renderMenuNames function. Now I wrote this when I was defining my function initially, because I looked ahead and new I would need it. But for this tutorial I am going step by step. So you will want to add a click event to the span tag you created, and then within that function call renderMenuDetails(menuObj). We call the menuObj within the parameter because we have access to it within function scope, which will allow you to access it in the renderMenuDetails function. and delete the call back from the bottom of renderMenuNames. The end result should look like this

```
const renderMenuNames = (menuObj) => {
    const spanTag = document.createElement("span")
    spanTag.textContent = menuObj.name
    spanTag.addEventListener("click", (e) =>{
        renderMenuDetails(menuObj)
    })
    menuDiv.append(spanTag)
}
```
You should now be able to click another name on the left and display its details 

![1,2, & 3 Done](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zmmu14p6oxrweajyutjz.png)

Congratulations 3 down 1 to go.

## Deliverable 4

_Challenge #4
The user should be able to add the menu items to their cart. When the user presses the 'Add to Cart' button, that number should be added to however many are currently in the cart._

  So there will be two functions we will need to write in order to do this one. The first will be the EventListener which will be a submit event since we are dealing with a form. So remember to prevent default within. Also we will be adding this EL to the Dom selector menuForm. Lastly add a call back function called menuCounter() no parameter necessary. It should look like this 

```
menuForm.addEventListener("submit", (e) =>{
    e.preventDefault();
    menuCounter()
})
```
Last step is to define menuCounter(). So I defined it using another arrow function. This is also where adding the menuCart to the renderMenuDetails is important. This is because without us defining that there, the cart amount will be the same for menu item. With it being defined in the renderMenuDetails it allows each one to have a separate cart. This also where the const currentCart = {} line in Dom Selectors comes in. Within menuCounter the first thing will be to declare a variable and assign it to parseInt(menuCartAmount.value), here we are grabbing the value from the form which is a string and making it a number. The next step is to grab currentCart.number_in_bag and assign it to parseInt(menuCart.textContent). It would be a good habit to console log adding cart to make sure you are getting a value you want and it is a number. After that we will want to add currentCart.number_in_bag to the verse variable we made in this function. We would do that with += between the two values. Lastly we want to take menuCart.textContent and assign it to the new updated currentCart.number_in_bag. The code should look something like this 

```
const menuCounter = () =>{
    const addingCart = parseInt(menuCartAmount.value)
    currentCart.number_in_bag = parseInt(menuCart.textContent)
     console.log(menuCartAmount.value)
    currentCart.number_in_bag += addingCart
    console.log(currentCart.number_in_bag)
    menuCart.textContent = currentCart.number_in_bag
}
```
On the Page you should now be able to add items to the cart and keep adding more to your cart. The final product should look like this 


![first addition to cart](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dmk1hma52119jjzot0fc.png)


![ALL BASE DELIVERABLES DONE](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/rqwpmrvhf3jq92c28hat.png)

## Summary
In this tutorial and walkthrough of a Mock CC from an instructor from FlatIron College, I walked you through each deliverable and how to achieve it. I also hope that I gave you a methodology or format in which you can use as a layout for any other challenge.

## The STEPS 
**1. Confirm you are in the right folder in the terminal. And run the  json-server --watch db.json command, or whatever the Readme tells you to run. 
2. Make sure to defer your script tag
3. Make a variable to assign your base Url too
4. Open the Readme preview and read every deliverable, paying attention to which Dom selectors you will need.
5. Underneath the Url variable Write out //Dom Selectors then underneath that use querySelector or getElementById and grab each Html ID or element you will need and assign them to variables.
6. Write out your fetch, and pay attention if you are grabbing an array or one object. In this example it was an Array. 
7.Console log the array then set the array to a forEach to grab each object, and within that function write a callback Fuction for the first thing you want to render and have the parameter be the name of the object.
8.While still in the fetch function or .then function but outside the forEach function write your cb function for renderdetails(array[0]). So this way on page load you get that first objects details on the page.
9. Next step define the cb function you made with the obj as the parameter.
10. Then write a cb at the bottom of that render for your details with the obj as a parameter so you have access to it within your next render function. 
11. Create a section for your Event Listeners and add them to the proper dom selectors. Within it write the cb function of what you want to happen.
12. Define that function, remember to pay attention to what type of data you are trying to use and change its type if necessary, ex: parseInt.
13. If you put your fetch in a function remember to initialize it at the bottom of your code and call the initializer. 
This is what the finished code should look like:
**
```
//Globals
const menuUrl = "http://localhost:3000/menu"

//Dom selectors
const menuDiv = document.getElementById("menu-items")
const menuDetails = document.getElementById("dish")
const menuImage = document.getElementById("dish-image")
const menuName = document.getElementById("dish-name")
const menuDescription = document.getElementById("dish-description")
const menuPrice = document.getElementById("dish-price")
const menuCart = document.getElementById("number-in-cart")
const menuForm = document.getElementById("cart-form")
const menuCartAmount =  document.getElementById("cart-amount")
const currentCart = {}
//eventListeners
menuForm.addEventListener("submit", (e) =>{
    e.preventDefault();
    menuCounter()
})
//fetches
const fetchAll = () =>{
    fetch(menuUrl)
    .then((response) => response.json())
    .then (menuArr => {
      console.log(menuArr)
      menuArr.forEach(menuObj => {
          renderMenuNames(menuObj)
      });
  renderMenuDetails(menuArr[0])
  });
}

//renders

const menuCounter = () =>{
    const addingCart = parseInt(menuCartAmount.value)
    currentCart.number_in_bag = parseInt(menuCart.textContent)
     console.log(menuCartAmount.value)
    currentCart.number_in_bag += addingCart
    console.log(currentCart.number_in_bag)
    menuCart.textContent = currentCart.number_in_bag
}

const renderMenuNames = (menuObj) => {
    const spanTag = document.createElement("span")
    spanTag.textContent = menuObj.name
    spanTag.addEventListener("click", (e) =>{
        renderMenuDetails(menuObj)
    })
    menuDiv.append(spanTag)
}
const renderMenuDetails = (menuObj) => {
    menuImage.src = menuObj.image
    menuName.textContent = menuObj.name
    menuDescription.textContent = menuObj.description
    menuPrice.textContent = '$' + menuObj.price
    menuCart.textContent = menuObj.number_in_bag
  };

//init
const init = () =>{
    fetchAll()
  }
  init()
```
   GOOD LUCK AND YOU GOT THIS!!!!!