Using axios in Vue.js with separate service?
Published: 2021-12-13 16:57:33

## Why is this necessary?

- 
It is little bit messy when so many API calls in a single component

- 
You make your components bigger and filled with  lot more logic that has nothing to do with the component itself which violates Single Responsibility Principle(SRP).Single Responsibility Principle is one of the most important aspect in writing good maintainable code.Writing great code is an art, but some principles can always help give your development work the direction it needs to head towards to produce robust and maintainable software.

- 
Same API methods could be used in different components which may causes code duplication and violates DRY principle.

- 
You will need to manually change all the places while you are going to modified your API.Really it's time consuming.

- 
OK,let's get started...

 Service.js
```javascript
import axios from "@/axios";

export async function getUserList() {

    const response = await axios
        .get(`/sign-up`)
    return response.data.users;

}

export async function userPost(rcv_data) {
    const response = await axios
        .post(`/sign-up/`, rcv_data)
    return response.data;

}
export async function getUserData(id, rcv_data) {
    const response = await axios
        .get(`/sign-up/${id}/`, rcv_data)
    return response.data.user;

}

export async function userUpdate(id, rcv_data) {
    const response = await axios
        .put(`/sign-up/${id}`, rcv_data)
    return response.data;

}
export async function userDelete(id) {
    const response = await axios
        .delete(`/sign-up/${id}`)
    return response.data;

}
```
In this scenario

- You can simply handle module wise API service in your component.

- 
One single module all API located in one place so it's easier to make any changes and resuse them in different component without duplicating code.

UserList.vue

```javascript
<template>
  <div class="container">
    <div class="row">
      <div class="col-md-12">
        <h1 class="text-center">User List</h1>
        <router-link to="/create-user">
          <button type="submit" class="btn btn-primary">Cerate User</button>
        </router-link>
        <table class="table table-striped table-dark">
          <thead>
            <tr>
              <th scope="col">#</th>
              <th scope="col">First Name</th>
              <th scope="col">Last Name</th>
              <th scope="col">Email</th>
              <th scope="col">Action</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(user, i) in user_list" :key="i">
              <th scope="row">{{ i }}</th>
              <td>{{ user.firstName }}</td>
              <td>{{ user.lastName }}</td>
              <td>{{ user.email }}</td>
              <td>
                <router-link
                  :to="{
                    name: 'EditUser',
                    params: { id: user.id },
                  }"
                >
                  <button type="submit" class="btn btn-primary">Edit</button>
                </router-link>

                <button
                  @click="userDelete(user.id)"
                  type="submit"
                  class="btn btn-danger"
                >
                  Delete
                </button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </div>
</template>

<script>
import { getUserList, userDelete } from "./Service";
export default {
  name: "UserList",
  data() {
    return {
      user_list: null,
    };
  },
  methods: {
    getUser: function () {
      getUserList().then((result) => {
        console.log("45", result);
        this.user_list = result;
      });
    },
    userDelete: function (id) {
      userDelete(id)
        .then((response) => {
          console.log("response", response.message);
          this.getUser();
        })
        .catch((error) => {
          console.log("error", error);
        });
    },
  },
  created() {
    this.getUser();
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

```

- 
In our component we are just dealing our data.If something went wrong simply return promise.

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/dsyvahixx03y9974ujqz.png)

EditUser.vue

```javascript
<template>
  <div class="container">
    <div class="row">
      <div class="col-md-12">
        <h1 class="text-center">User List</h1>
        <form>
          <div class="form-group">
            <label for="exampleInputEmail1">Email address</label>
            <input
              type="email"
              class="form-control"
              v-model="input_data.email"
              id="exampleInputEmail1"
              aria-describedby="emailHelp"
              placeholder="Enter email"
            />
          </div>
          <div class="form-group">
            <label for="exampleInputPassword1">Fist Name</label>
            <input
              type="firstName"
              class="form-control"
              placeholder="First Name"
              v-model="input_data.firstName"
            />
          </div>
          <div class="form-group">
            <label for="exampleInputPassword1">Last Name</label>
            <input
              type="last_name"
              class="form-control"
              placeholder="Last Name"
              v-model="input_data.lastName"
            />
          </div>

          <button
            type="submit"
            class="btn btn-primary"
            @click.prevent="userUpdate"
          >
            Submit
          </button>
        </form>
      </div>
    </div>
  </div>
</template>

<script>
import { getUserData, userUpdate } from "./Service";
export default {
  name: "EditUser",
  data() {
    return {
      input_data: {
        firstName: null,
        lastName: null,
        email: null,
      },
    };
  },
  methods: {
    getUserData: function () {
      getUserData(this.$route.params.id, this.input_data)
        .then((response) => {
          console.log("response", response);
          this.input_data.firstName = response.firstName;
          this.input_data.lastName = response.lastName;
          this.input_data.email = response.email;
          // this.$router.push("/");
        })
        .catch((error) => {
          console.log("error", error);
        });
    },
    userUpdate: function () {
      userUpdate(this.$route.params.id, this.input_data)
        .then((response) => {
          // console.log('response',response.message)
          this.$router.push("/");
        })
        .catch((error) => {
          console.log("error", error);
        });
    },
  },
  created() {
    this.getUserData();
  },
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
</style>

```

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/sumk6kwdczkl2gjib0dq.png)

## Epilogue
I hope this helps you.Do not hesitate to leave a comment if you have any query feel free to ask.Thank you for reading.Happy coding...

https://github.com/Julfikar-Haidar/separate_service