Sometimes you would just like to have a very descriptive list of all beers so you could see their type, color, each beer's percentage of alcohol, or which beer is well pared with some food. In this lab, you will create a web app where the user will be able to see a list of beers, get random suggestions, and read a very descriptive explanation of each beer.
"How will we get all of this information?", you might ask. Well, we will be using an npm package 📦 as our data source.
For this exercise, we will work with the PunkAPI npm package. In the background, the package communicates with a remote database that contains all of the beers. The package enables us to use its methods that can help us to retrieve beers. Each beer has some properties, and we can play around with this data to practice working with Handlebars templates, layouts and partials.
In this lab, we can also practice reading external (PunkAPI) docs and learn how to get what we need from the database.
- Fork this repo
- Then clone this repo.
- Upon completion, run the following commands:
$ git add .
$ git commit -m "done"
$ git push origin master- Create Pull Request so your TAs can check up your work.
To run our application, the first thing you have to do is to install all of its dependencies. Run the following command:
$ npm installTo run the app:
$ node app.js
# you can also run: npm startOur starter code includes the basic configuration needed to run our app. The / route is set to render the index.hbs file. Let's start by creating a layout.
Inside of the views folder, create a layout.hbs file. In the bonus iteration, you can give your app some style, but for now, let's focus on the logic.
Remember to add the {{{ body }}} to the main layout.
Add a navbar that includes links to 3 pages:
- Home ==> should navigate to
/. - Beers ==> should navigate to
/beers. - Random Beer ==> should navigate to
/random-beer.
Layout done, let's move to creating these three pages.
- The first page should be Home and should be rendered on
/. The file that gets rendered isindex.hbs. - This file should include the beer image, which you can find at
/public/images. Together with the image,index.hbsshould have two links:Check the Beers!andCheck a Random Beer. Both links should navigate to the corresponding routes (which we previously defined in our navbar as well). Later, you can style theseatags to make them look like buttons.
The next thing we will be working on is a page where we can present all the beers we will retrieve from the remote database. This page will be rendered every time the user visits the the /beers route.
This leads us to the conclusion that in this step, we have the two main focus areas:
- the
/beersroute and - the
beers.hbsview.
In this step, we will have a couple of micro-steps:
- Create a
/beersroute inside theapp.jsfile. - Inside the
/beersroute, call thegetBeers()method (the PunkAPI provides this method, and you can find more about it here). Calling the.getBeers()method returns a promise that should be resolved with an array of 25 beers. - Down the road, you should pass that array to the
beers.hbsview.
The example of how this method works is shown below:
punkAPI
.getBeers()
.then(beersFromApi => console.log('Beers from the database: ', beersFromApi))
.catch(error => console.log(error));- Create a
beers.hbsfile to render every time we call this route. - This file should have access to the beers we get as a response from the database. Remember, you should call the
rendermethod after getting the beers array. Hint: That means inside of the function you're passing to thethenmethod. 😉 - On the
beers.hbsview, loop over the array of beers using an{{#each}}loop. Display an image, name, description and tagline.
Now, when you click on the Beers link on the top navigation or on the Check the beers button, you should be able to see all the beers. Boom! 💥
As in the previous step, we will have to focus on creating a route to display a random beer. When a random beer is retrieved, we have to pass it to the view.
- Let's create the
/random-beerroute. - Inside the route, you should call the PunkAPI
getRandom()method. It returns a promise that will resolve with a different beer object on every call. Look at the documentation to understand the structure of the data that you're supposed to get back. 👍
The example of how this method works is shown below:
punkAPI
.getRandom()
.then(responseFromAPI => {
// your magic happens here
})
.catch(error => console.log(error));- Eventually, the received beer needs to be passed to the
random-beer.hbsfile. You still don't have this file, so let's proceed to create it.
- The
random-beer.hbsshould display the random beer that was retrieved from the database. You should display an image, name, description, tagline, food pairing and brewer tips. The following image shows how this page could look like if you give it a bit of style. However, the styling will come later, so, for now, focus on rendering all the information:
Now, every time the user clicks on the Random beer link in the navbar or on the Check a random beer button on the home page, they should see this page with a new, random beer.
You've just finished all the mandatory iterations. Good job!
Let's proceed to the bonus iterations.
:::info
On every iteration, you should render a partial passing the information regarding the corresponding beer.
:::
Partials represent templates that are likely to be reused.
Let's see what beer properties we display on the /beers (the beers page) and compare them with the properties we displayed on the /random-beer (random beer) page:
| properties/ page | /beers |
/random-beer |
|---|---|---|
| image | ✅ | ✅ |
| name | ✅ | ✅ |
| description | ✅ | ✅ |
| tagline | ✅ | ✅ |
| food pairing | ❌ | ✅ |
| brewer tips | ❌ | ✅ |
As we can see, we have 4 in common properties, which means our code could be a bit more DRY if we refactor it using partials.
You should create a partial to show each beer.
- First, we need to register where our
partialswill be located. So you need to add the following code to theapp.jsfile:
hbs.registerPartials(path.join(__dirname, 'views/partials'));- Next, you should create a
partialsfolder inside theviews, andbeerpartial.hbsfile inside thepartialsfolder (Note: We're not including dashes in thehbspartial names, since handlebars partials need to follow the same naming conventions as JavaScript variables). - Our
beerpartial.hbswill display the properties that both views share: image, name, description, and tagline of the beer. - Now, you can go ahead and plug in this partial in the
beers.hbsview inside theeachloop.
After creating the partial, and looping over the array of beers, on our /beers route, we should have the following:
- Also, you can use it in the
random-beer.hbspage.
Our code shrunk by a lot just because we managed to create a reusable piece of code (the partial), which we can now place wherever we need to use this set of properties.
Make all the beers on the beers page clickable. If users click on a specific beer, they should be able to see a page with the detailed information of that particular beer. You can reuse the same partial you used for iteration 5. As a matter of fact, you should. That's what partials are for. The trick is to wrap an anchor tag around every beer that has the beer id in the href property. Something like:
<a href="/beers/beer-i3f4d34s34b"><!-- name of the beer --></a>To understand how you can get the id from the URL, read this section of the Express docs.
To find out how you can get an individual beer from the punkAPI using the beerId, check out the .getBeer(id) method on the punkAPI docs.
The overall layout should look like this:
You will find the colors and fonts on the css file. Remember to link the css file to your main layout.
Let your artsy side shine! ✨
Happy Coding! 💙




