Svelte 3 - How to connect your app with a Rest API Axios
Tags: svelte, javascript, beginners, webdev
Published: 2020-06-16 01:38:04

Hello everybody, continuous with the Svelte post series, Today I want to share one technique that normally use to connect my Web applications with my backend or Rest API. 

I will talk about his advantages and how easily you can integrate with your project, even if you are starting in the world of the Front End. 

## Decoupling third-party libraries.
Most of the time to connect with a Rest API, we need to implement a Third-party library and more if we want to handle complex configurations.
In this case, we will use **Axios**, because it's very easy and practical to implement.

**This technique consists in two steps.**
1. Create a good folder structure to split the responsibility to perform the action and define the concrete action.
2. Have the third-party library implementation in his own file.

**Some of the advantages that We can see are the following.**
1. Easy way to find the API communication methods.
2. We can easily change the HTTP request library.
3. Single point of Http calls.
4. Advanced configuration of the Third-party library.
6. Keeping a clean code.

## Let's Code!!

### 1. Install Axios.
To start working with _Axios_ we need to install the library executing the `npm` command in our project.
``` 
npm install axios
```
### 2. Create Axios implementation.
One that we have our library ready, we need to create a folder called `services` to add all our third parties libraries implementation as _Axios_, _signalR  client_, date format library (_moment_), etc. 

The reason for this folder, it is to find all the abstraction of the libraries and in the case that we want to change any library, we can quickly modify these files without modify the whole application.

Okay, now we will create a file with the name of `Api.js`, to add all the HTTP methods that we need to use.
I will leave the code here, I think that is very simple and self-described.

```javascript
// Api.js
import axios from "axios";

// Create a instance of axios to use the same base url.
const axiosAPI = axios.create({
  baseURL : "https://pokeapi.co/api/v2/" // it's not recommended to have this info here.
});

// implement a method to execute all the request from here.
const apiRequest = (method, url, request) => {
    const headers = {
        authorization: ""
    };
    //using the axios instance to perform the request that received from each http method
    return axiosAPI({
        method,
        url,
        data: request,
        headers
      }).then(res => {
        return Promise.resolve(res.data);
      })
      .catch(err => {
        return Promise.reject(err);
      });
};

// function to execute the http get request
const get = (url, request) => apiRequest("get",url,request);

// function to execute the http delete request
const deleteRequest = (url, request) =>  apiRequest("delete", url, request);

// function to execute the http post request
const post = (url, request) => apiRequest("post", url, request);

// function to execute the http put request
const put = (url, request) => apiRequest("put", url, request);

// function to execute the http path request
const patch = (url, request) =>  apiRequest("patch", url, request);
 
// expose your method to other services or actions
const API ={
    get,
    delete: deleteRequest,
    post,
    put,
    patch
};
export default API;
```
Now we are ready to do HTTP calls from any place of our project. 🤗

### 3. Using the API service.

This step is optional, but personally I like to keep all my API calls in a folder called **api** and create a file for each API resource.
For example, in this case, I will create a file called _pokemon.js_ because the resource that I will use is **Pokemon**.

In this file, I'm using my `Api.js` service and I handle the Http errors that I could get.

```javascript
// pokemon.js
// Implementations for all the calls for the pokemon endpoints.
import Api from "../services/Api";

// Method to get a list of all Pokemon
export const getPokemonList = async () => {
    try {
      const response = await Api.get("/pokemon?limit=500");
      return response.results;
    } catch (error) {
      console.error(error);
    }
};

// Get a pokemon details by name
export const getPokemonByName = async(name) => {
    try {
      const response = await Api.get(`/pokemon/${name}`);
      return response;
    } catch (error) {
      console.error(error);
    }
};
```

### 4. Calling the APIs

It is time to call our methods to get the data into our _Svelte_ page (component).
This page will be very simple, just with a pokemon list and a section with the details of the pokemon, image, name, and type.  I want to focus on the functionality to connect with the APIs.

```javascript
<script>
  // PokeList.svelte
  const pageName="Poke-List";
  import { onMount } from 'svelte';
  import { getPokemonList, getPokemonByName } from "../api/pokemon"; // import our pokemon api calls

  let pokemonDetail = {};
  let pokemonList = [];

  // Get the data from the api, after the page is mounted.
  onMount(async () => {
    const res = await getPokemonList();
    pokemonList = res;
  });

  // method to handle the event to get the detail of the pokemon.
  const handleOnClick = event =>{
    const name = event.target.name;
    getPokemonByName(name).then(res => {
      pokemonDetail= {
        name,
        types: res.types,
        image: res.sprites.front_default
      };
    });
  };

  const getPokemonTypes = () => {
    return pokemonDetail.types.map(e => e.type.name).join(",");
  };
</script>

<style>
main {
		text-align: center;
		padding: 1em;
		max-width: 240px;
		margin: 0 auto;
	}

	h1 {
		color: #ff3e00;
		text-transform: uppercase;
		font-size: 4em;
		font-weight: 100;
	}

	@media (min-width: 640px) {
		main {
			max-width: none;
		}
	}
  .pokemonDetails{
    float: right;
    width: 500px;
     text-transform: capitalize;
  }
  .pokemonList{
    width: 300px;
    float: left;
    max-height: 400px;
    overflow-y: auto;
  }
  .pokemonList li{
    list-style: none;
    text-align: left;
    margin-bottom: 5px;
  }
  .pokemonList .pokeName{
    text-transform: capitalize;
    font-size: 18px;
    font-weight: 700;
  }
  button {
    background: none!important;
    border: none;
    padding: 0!important;
    color: #069;
    text-decoration: underline;
    cursor: pointer;
  }
</style>

<main>
	<h1> {pageName}!</h1>
    <p>Welcome to my <b>{pageName}</b></p>
      <ul  class="pokemonList">
        {#each pokemonList as pokemon}
            <li>
              <label class="pokeName">
                {pokemon.name}
              </label>
              <button 
                type="button" 
                name={pokemon.name}
                on:click={handleOnClick}>See Details</button>
            </li>
        {/each}
      </ul>
      <div class="pokemonDetails">
        <h3>Pokemon Detail</h3>
        {#if pokemonDetail.image}
         <img 
              class="pokeimage"
              src={pokemonDetail.image}
              alt="pokeimage"/>
          <label><b>{pokemonDetail.name ? pokemonDetail.name : ""}</b></label>
          <label><b>Types: </b>{pokemonDetail.types ? getPokemonTypes() : ""}</label>
        {/if}
      </div>
</main>
```
### Wrapping up

As you see, it 's very quick and easy to connect with a Rest API using Axios and also has a clean code.

After applying the previous code implementations, This is how to look at my code.
**Note:** The new files and folder that we added are in yellow.
![Last modification](https://dev-to-uploads.s3.amazonaws.com/i/96jb4zhkw3u28jampz05.png)
 
And here is how looks our PokeList running.

![Poke List](https://dev-to-uploads.s3.amazonaws.com/i/8g5wr0k8vtsypvgwlh3b.png)


I hope that this implementation was helpful to you. If you have any questions or suggestions leave in the comment section I will be reading you. 😉

Wait, if you don't are familiar with Svelte I high recommend checking my other posts where I explain how to create your first Svelte project and implement pages routing.

1. [Quickstart with Svelte3 - Creating your first component](https://dev.to/lukocastillo/quickstart-with-svelte-3-creating-your-first-component-3mm2)
2. [How to integrate with svelte-routing](https://dev.to/lukocastillo/svelte-3-how-to-integrate-with-svelte-routing-4j3b)