Display an item’s information from API data

Display product prototype

This exercise will demonstrate how to display a product or item’s information from the API data. You should route to an item’s page from the list of items and displays its information.  More details are described in the acceptance criteria below.

Objective

Build a responsive web page that displays the item’s information from API data

Description

This is a continuation of the exercise “Fetch and display menu items“. The goal of this exercise is to build a page that looks similar to the prototype shown below.

Prototype of the item’s page

item's information from API- prototype

A page for an individual item should be opened when the respective item is clicked from a list of menu items,
The exercise can be done with HTML, CSS, and JavaScript, but it is recommended to use modern front-end libraries or frameworks such as React.js, Vue.js, or Angular. The solution provided is in Vue.js and also uses Vuetify.js which is a material design UI library for Vue.js.

The menu items are saved in a database and the data is made available through REST API.

API documentation:

Get a single item:

fetch("https://my-json-server.typicode.com/projectecode/demo/menu/1")
  .then((res) => res.json())
  .then((json) => console.log(json));

Response

//output
{
  "id": 1,
  "title": "Cheese Burger",
  "img": "https://cdn.pixabay.com/photo/2017/12/09/23/04/bread-3008950_960_720.jpg",
  "price": "3.75",
  "description": "Our burger is seasoned with a pinch of salt, pepper and onion powder. It is topped with pickles, lettuce, tomato, onions, and American cheese. Assembled on a perfectly toasted bun.",
  "calories": "450",
  "proteins": "32gm",
  "category": "Entree"
}

 

Template:

You can use the following template to fork and get started:

https://codesandbox.io/s/displayitemtemplate-3z76d

Acceptance criteria

  • The item’s title and image on the menu page should include a hyperlink to open the respective page for the item.
  • The id of the item should be passed to the new component (page) as a route parameter or through props.
  • Fetch the item’s details from the API.
  • Display item’s image, title, cost, category, and description as shown in the prototype design
  • Add an “Add to order button
  • The text on the “Add to order button should be updated to show “View order when clicked.
  • Add a “Main menu” button. Clicking this button should navigate back to the Menu page.
  • The webpage should be responsive
  • Use material design as a standard design practice

Hints

  • Use the native fetch function in javascript or libraries such as axios to get data from an API.
  • The REST endpoint for GET method is 'https://my-json-server.typicode.com/projectecode/demo/menu/1'
  • Use a design library such as bootstrap as a boilerplate for making responsive design
  • Add a flag to check if the item is added to the order. If the item is added to the order, set it to true and update the text on the button

 

Solution Walkthrough

Menu component Menu.vue is updated to add a router link that will open the item component Item.vue.

<!-- Menu.vue -->
<router-link :to="`/item/${item.id}`" exact>
  <v-img height="200" :src="item.img"></v-img>
  <v-card-title>
     <span style="margin:auto"> {{ item.title }} </span>
  </v-card-title>
  <v-card-text>
    <div class="text-center">
      <v-chip color="success" outlined class="pa-4">
        <v-icon left>
          fastfood
        </v-icon>
        {{ item.category }}
      </v-chip>
    </div>
  </v-card-text>
</router-link>

Create a new Item.vue file which will have the <Item> component. Import it in Menu.vue and register the component.

// Menu.vue

//Import component
import Item from "./Item.vue";
// Menu.vue


//Register component
  components: {
    Item
  },

 

As per the API documentation, we can get the details of an individual item from its “id”. This id is passed to the “Menu.vue” component as a route parameter and is available when the component is created. We can save this as a data property. Also, create a method that fetches the product’s data when the component is created.

// Item.vue

//Life cycle hook - created
  created(){
    this.id = this.$route.params.id;
    this.fetchItem();
  },

 

// Item.vue

//Data properties
  data: () => ({
    id: null,
    item: {},
    addedToCart: false,
  }),

 

As the name suggests fetchItem method will get the item’s data and we will save the response in a data property called “product” which will be an object.

// Item.vue

//Fetch data
  fetchItem(){
    fetch(`https://my-json-server.typicode.com/adityaekawade/demo/menu/${this.id}`)
    .then(res=>res.json())
    .then(json=> this.item = json)
  },

As per the tasks, we need to also create an “Add to order” button whose text is updated when it is clicked.

<!-- Item.vue -->
<v-btn color="#dd0031" style="color: white" block large>
  <span @click="addToCart" v-if="!addedToCart">
      Add to order
   </span>
   <span v-else>View order</span>
</v-btn>

Previously, we had added a data property addedToCart. So if the addedToCart is false, meaning, the item is not added to the order, the “Add to order button is displayed. Else if the addedToCart is true, the text on the button is updated and it shows “View order”.

When “Add to order” button is clicked, it call the addToCart, which is defined below. For this exercise, it simply toggle the state of the data property addedToCart to be true.

//Item.vue

  addToCart(){
    this.addedToCart = true;
  }