My first single page app (SPA)
Tags: webdev, javascript, css, html
Published: 2023-05-15 06:17:50

Hello everyone. My name is Jiyong and I am a student at Flatiron. 
Welcome to my first blog post and it's a project walkthrough!

This is the initial page of the app. It's called World Countries Finder.

![Project webpage](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/95wz812q71nf3q8qsao8.png)

This app is a simple web page that will fetch data from an API and display a card with a given input, in this case a country name. The form will receive the data from the API and display the country's capital city, continent, the flag, and spoken language(s). The web page has a 3 files: an HTML, CSS, and JavaScript. It has a Heading, background image, and a search box. The search box was created with a form element in html and it includes the class name, button element with 'Submit' text. 

![form](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wkaiep5khh3433pggggv.png) 

![input form box](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/o4as6o6qdposf6z6o5dm.png)

The background image was implemented using CSS on the body element with background: url(path), with a height of 100vh(viewport height). Viewport height is the viewable screen's height. The value of 100vh will fill background image to the entire screen within the body element.

![background image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/68t9dsukf0kl4jwqe9ob.png)

After the correct input is received, the app will create a 'card' and display it below the search box.


![card created](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6b5o6xp5zrp5xlfxoqx9.png)

The web page can fill up to 5 cards wide and will fill on the next line.


![number of cards displayed](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dzb8laj4wyfkmqu95hpv.png)

If the country name is not found or has an incorrect spelling, it will display an alert.


![input error alert](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fwf1wcub9wjy8yj6j56x.png)


That's the basic functionality of the single page app.

But how does it all work? For that, we need to go to the JS file and Event handlers for form submissions and check out Fetch API.

Event handlers basically take an event type such as a 'click', 'mouseover', or 'mouseup' and a listener, which is an object that receives a notification or a Javascript function, such as a callback function. Please visit MDN web docs for more information.
From MDN: 

addEventListener(type, listener)
addEventListener(type, listener, options)
addEventListener(type, listener, useCapture)

My app used an Event listener that 'listened' for a 'submit' event in the form and called back a function 'getCountries':

![Event handler](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0tm38tannhu8a0u9jrdx.png)

The getCountries() function has an 'if' statement to check if the input form is not empty denoted with if (inputValue === '') with an alert window if the condition is not met. Also it is calling the API using fetch API to receive data in JSON format after the input form condition is true. 


![input condition check](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bu2mv17bdrygpwa0ibp4.png)

fetch API

![fetch API getting data](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hfu6ow9glb1md0l86ac7.png)

The first .then receives data and transforms in JSON format. The second .then 'implements' that JSON using .map method to create a new array of results from the JSON object and is defined with a variable 'matchingData' and it uses a callback function to return a single element in the new array. (listOneCountry(matchingData.shift()); shift taking the first element of the new array.

MDN: 
map(callbackFn)
map(callbackFn, thisArg)

The second .then also has a condition: if the 'matchingData.length>0' run the listOneCountry() function, else display an alert 'No match found'.

Finally,
The listOneCountry() function 'creates' a card with information such as spoken languages, continent, the flag image, using different types of html elements, such as 'div', 'p', and 'img src'. Some data need to be 'extracted' using the Object.values method to get the value from the object. After that the 'card' was appended (using .appendChild) to display on the DOM. 

![create card function](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dl0d5vswk4mw1ioczte5.png)
 
Result:


![final product](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/anli3i2zk9cw7a68udv7.png)

I hope this project was helpful and there is more to come! This is not the final product!

References:

MDN web docs:
https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map