Learn full-stack web development using fastn in a week
Learn Now

Dynamic country list page

Hi Guys, welcome to the video.

In this video we will build a dynamic country list page.

For this, we will request the JSON data using http processor and store it in fastn records and later in the video, we will create a country list page that will display the list of countries in form of cards. Each country card will display country's flag and country's common name and also display values of population, region and capital.

We will do this in three parts.
  • In the first part, we will do data modelling by declaring all the records in a separate document.

  • In the second part, we will create a card component that will contain the data.

  • And in the third part of the video, we will make use of http processor to request the data and store in a list and display the data by calling the component.
The JSON data is structured in a way, that some properties are nested within another property. Let's visualise it with the help of an illustration:

So the country has name, capital, region, population, and flags properties at one level. common and official names of a country are grouped under the name property.

Some countries have more than one capital, so we will create a list for capital property.

Also, flags have nested properties "svg" and "png" in the JSON data. We will utilize the "svg" property.

First Part: data modelling

So I have this package country-details in my machine.

I will create a separate document called models.ftd where we will do the data modelling using records.

So let's create the first record.
-- record country:
country-name name:
integer population:
string region:
string list capital:
country-flag flags:
Lang:
ftd

name property has a type that itself is a record which we will create in a bit.

population is an integer while region and capital are of string type. Also, some countries have more than one capital hence we will create the list of capital.

Last but not the least, flags also has a record datatype.

Let's declare the country-name and country-flag records too.
-- record country-name:
optional string common:
string official:
Lang:
ftd
-- record country-flag:
caption svg:
Lang:
ftd

The country-name record has two properties common and official, both of string type.

And the country-flag record has svg property which can be passed as caption.

So this way we are done with the data-modelling part.

Second Part: create a card component

Moving to the second part of the video, we will create a card component.

I will put all the components inside a components folder.

In this folder, I have created a card.ftd document.

Since we are going to display the value of properties declared in the records in models.ftd hence at the top of the card.ftd we will import that document.
-- import: country-details/models
Lang:
ftd

In the import line we will write the package name, slash, and the document name we are importing, that is, models

Now, create a component let's say country-card.
-- component country-card:

-- end: country-card
Lang:
ftd
Now let’s add a property country and the data type will be record country that we created in the models document. We have also marked it as caption, to make easy for users of this component.
caption models.country country:
Lang:
ftd

And structure the card in a way that I showed at the start using columns and row and putting the flag, common name, population, region and capital. And apply fastn properties appropriately.

Main column
-- ftd.column:
width.fixed.px: 260
height.fixed.px: 375
overflow: auto
border-radius.rem: 0.5
margin.rem: 2
cursor: pointer
border-width.px: 1
border-color: #dedede
Lang:
ftd
Image
-- ftd.image:
src: $country-card.country.flags.svg
width: fill-container
height.fixed.percent: 50
Lang:
ftd
Field column
-- ftd.column:
padding.rem: 1
spacing.fixed.rem: 0.5
width: fill-container
border-color: #dedede
height: hug-content
border-top-width.px: 1

-- ftd.text: $country-card.country.name.common
style: bold
role: $inherited.types.copy-regular

-- ftd.row:
spacing.fixed.rem: 1

-- ftd.column:
spacing.fixed.rem: 0.5

-- ftd.text: Population:
role: $inherited.types.label-large
style: semi-bold

-- ftd.text: Region:
role: $inherited.types.label-large
style: semi-bold

-- ftd.text: Capital:
if: { len(country-card.country.capital) > 0 }
style: semi-bold
role: $inherited.types.label-large

-- end: ftd.column
Lang:
ftd
values column
-- ftd.column:
spacing.fixed.rem: 0.5

-- ftd.integer: $country-card.country.population
role: $inherited.types.label-large

-- ftd.text: $country-card.country.region
role: $inherited.types.label-large

-- ftd.text: $capital-name
style: bold
role: $inherited.types.label-large
for: $capital-name, $index in $country-card.country.capital

-- end: ftd.column

-- end: ftd.row

-- end: ftd.column

-- end: ftd.column

-- end: country-card
Lang:
ftd
We can also apply default shadow and on-hover shadow to the card component to make the component look good.
-- ftd.shadow default-card-shadow:
color: #efefef
blur.px: 5
spread.rem: 0.2

-- ftd.shadow hovered-card-shadow:
color: #d5e3db
blur.px: 5
spread.rem: 0.2
Lang:
ftd

So, we will add shadow property to the component, and create a mutable boolean variable.

;; shadow properties
-- component country-card:
caption models.country country:
optional ftd.shadow shadow:      ;;<hl>
boolean $is-hovered: false       ;;<hl>
Lang:
ftd
And do the event-handling. ;; add these to main column
shadow: $default-card-shadow
shadow if { country-card.is-hovered }: $hovered-card-shadow
$on-mouse-enter$: $ftd.set-bool( $a = $country-card.is-hovered, v = true )
$on-mouse-leave$: $ftd.set-bool( $a = $country-card.is-hovered, v = false )
Lang:
ftd

Third Part: display the output

We are done with the second part. Everything needed to display the data is ready. Now, We will request the JSON data, and display the data in the card using the component.

In the index.ftd document , We will need the two documents and processors so import the processors and the two documents.
-- import: fastn/processors as pr
-- import: backend/models
-- import: backend/components/card
Lang:
ftd
We will create a list of countries and the datatype will be record country that we created in models document.
-- models.country list countries:
$processor$: pr.http
url: https://restcountries.com/v3.1/all
Lang:
ftd

The data will be stored using processors by doing http request to the endpoint we will give as URL.

Now we will call the component country-card from card document and we will wrap it inside the row container component.
-- ftd.row:
wrap: true
spacing: space-around
padding.rem: 2
border-radius.rem: 1

-- card.country-card: $country
for: $country in $countries 

-- end: ftd.row
Lang:
ftd

We have passed the reference value of property country of the country-card component in the caption.

And, applied for loop.

Closing remarks

I hope you have learnt with me and found this video easy to follow.

Join us on Discord, and share your package which you will create following this video. You can share it on the discord's show-and-tell channel.

Thank you guys, keep watching these videos to learn more about fastn. Checkout the fastn website.

Support us by clicking on this link and give us a star ⭐ on GitHub and join our fastn community on Discord.

Final Video

Copyright © 2023 - fastn.com