Advanced JS

Advanced topics in javascript

In the latest versions of javascript it is possible to code in a functional style and use advanced formatting with templare literals. This gives a lot of opportunities to write more concise code but also to make the students think about function composition and implementing the DRY principle.

I have created a repl with the pizza site rewritten to show what the code could look like: Advanced pizzalist example.

There is a lot to take in here and I will briefly explain the code snippets below. I will not explain the principles of functional programming as this is an example and not a tutorial. Maybe some other time :-).

Using a shared display function (DRY)

One of the challenges of programming is to master the DRY principle (Don’t repeat yourself). When you repeat pieces of code there is a much larger risk of making errors. And if you make changes to a function or algorithm you have to change all occurences in your code. I have implemented it below:

const displayPizzaList = pizzas =>
  pizzas
    .map(p => `
      <li>
         Navn: ${p.pizzaName}.<br/>
         Pris: ${p.pizzaPrize} kr.<br/>
         ${showType(p.pizzaType)}.<br/>
         ${showGarlic(p.garlic)} Hvidløg.
      </li>     
    `)
    .join('');

As it is possible to mix functions with data you can map over the properties of each pizza object and construct the HTML output using regular text, variables and helper functions. The two helper functions used to construct the HTML are:

const showGarlic = garlic => garlic === true ? 'Med' : 'Uden'

const showType = type => type === 'normal' ? 'Almindelig' : 'Indbagt'

Selecting the pizzas to show

I have rewritten three of the functions that selects pizzas to show the various possibilites:

const cheapSortedPizzas = pizzas =>
  pizzas
    .filter(p => p.pizzaPrize < 80)
    .sort((a, b) => a.pizzaPrize - b.pizzaPrize)

const noGarlicSortedPizzas = pizzas =>
  pizzas
    .filter(p => p.garlic === false)
    .sort((a, b) => a.pizzaPrize - b.pizzaPrize)

const cheapestPizza = pizzas =>
  pizzas
    .reduce(byLowestPrice)
    .pizzaName

The functions all use the traditional functional toolkit (filter, map, reduce) as well as a sort function.

Composing functions

One of the key principles of functional programming is composing functions. This supports the DRY principle as it lets the programmer reuse pieces of code in several places (see DRY above).

const compose = (f, g) => x => f(g(x));

const showCheapSortedPizzas = compose(displayPizzaList, cheapSortedPizzas);

const showNoGarlicSortedPizzas = compose(displayPizzaList, noGarlicSortedPizzas);

Here we use the functions for finding the selection of pizzas and compose them with the displayPizzaListfunction.

Using template literals

Template literals offer a much nicer way of concatenating strings with function output. A good overview can be found at MDN.