DEV Community

Cover image for Svelte 3 - How to connect your app with a Rest API Axios
Luis Castillo
Luis Castillo

Posted on

Svelte 3 - How to connect your app with a Rest API Axios

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.
  5. 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.

// 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.

// 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.

<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

And here is how looks our PokeList running.

Poke List

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
  2. How to integrate with svelte-routing

Top comments (5)

Collapse
 
hydracorey profile image
Corey Vincent

What did you mean by:

const axiosAPI = axios.create({
  baseURL : "https://pokeapi.co/api/v2/" // it's not recommended to have this info here.
});
Enter fullscreen mode Exit fullscreen mode

Are you just suggesting we get the 'baseURL' constant from somewhere more global, or that there's a way to secure/hide that value? I was under the impression the front end can be seen by pretty much anyone...

Collapse
 
rubendutchtelco profile image
RubenDutchtelco

You are correct about the fact that all front-end code is always visible to the end user.

I think the recommended method the author is referring to is a .env like file (npmjs.com/package/dotenv). Which does not hide the values but makes them more variable and easier to change without having to alter your code.
You might want your front-end connecting to different base URL's depending on what environment it is running (dev, staging, prod).

Collapse
 
hydracorey profile image
Corey Vincent

Thanks for the response. Your points make sense.

Collapse
 
faustineshaw97 profile image
faustineshaw97

Hi. Hope you are doing well. I tried using books for JavaScript but I realised that perhaps watching someone else code and following along like in a video tutorial may be more helpful while learning JavaScript. Any free video tutorials/courses like on YouTube you know of that teach JavaScript from scratch well, ie from basics, and then moves on to like equipping me to build projects myself? Thanks. Also I might need to relearn HTML and CSS from the beginning, which YouTube tutorials could you point me towards?

Collapse
 
joshuawoodsdev profile image
JoshuaWoods

Dude this is good I feel like this is missing something when I started it I didnt see anything. what about the app.js?