Vue Fetch example – Get/Post/Put/Delete with Rest API

JavaScript Fetch API provides an interface for accessing and manipulating HTTP requests and responses. In this Vuejs tutorial, we will create Vue Fetch example to make Get/Post/Put/Delete request with Rest API and JSON data.

Related Post:
Javascript Fetch API tutorial: Get/Post/Put/Delete example


Vue Fetch example Overview

We will build a Vue Client with Fetch API to make CRUD requests to Rest API in that:

  • Vue Fetch GET request: get all Tutorials, get Tutorial by Id, find Tutorial by title
  • Vue Fetch POST request: create new Tutorial
  • Vue Fetch PUT request: update an existing Tutorial
  • Vue Fetch DELETE request: delete a Tutorial, delete all Tutorials

vue-fetch-example

This Vue Fetch Client works with the following Web API:

MethodsUrlsActions
POST/api/tutorialscreate new Tutorial
GET/api/tutorialsretrieve all Tutorials
GET/api/tutorials/:idretrieve a Tutorial by :id
PUT/api/tutorials/:idupdate a Tutorial by :id
DELETE/api/tutorials/:iddelete a Tutorial by :id
DELETE/api/tutorialsdelete all Tutorials
GET/api/tutorials?title=[keyword]find all Tutorials which title contains keyword

You can find step by step to build a Server like this in one of these posts:

Remember that you need to configure CORS: Access-Control-Allow-Origin: *.
It helps the REST APIs can be accessed by any origin.

Vue Fetch data from API example

fetch() returns a Promise that resolves with a Response object, which is fulfilled once the response is available.

const responsePromise = fetch(resourceUrl [, options]);

The Response object we mention above represents the entire HTTP response, it does not directly contain the response body. To get the actual JSON body of the response, we use response.json() method.

We can also access metadata such as headers, status, statusText, type, url from the Response object.

The response Promise does not reject on HTTP errors (for example: 404, 500). It only rejects when encountering a network error. So we need to check for HTTP errors with response.ok status and/or response.status properties.

For more details about fetch() method (with params, json, body, headers, error handling…), kindly visit:
Javascript Fetch API tutorial: Get/Post/Put/Delete example

Let’s implement a Vue component to fetch JSON data from API:

  • get all Tutorials
  • get Tutorial by Id
  • find Tutorial by title
<template>
  <div id="app" class="container">
    <div class="card">
      <div class="card-header">Vue Fetch GET - BezKoder.com</div>
      <div class="card-body">
        <div class="input-group input-group-sm">
          <button class="btn btn-sm btn-primary" @click="getAllData">Get All</button>

          <input type="text" ref="get_id" class="form-control ml-2" placeholder="Id" />
          <div class="input-group-append">
            <button class="btn btn-sm btn-primary" @click="getDataById">Get by Id</button>
          </div>

          <input type="text" ref="get_title" class="form-control ml-2" placeholder="Title" />
          <div class="input-group-append">
            <button class="btn btn-sm btn-primary" @click="getDataByTitle">Find By Title</button>
          </div>

          <button class="btn btn-sm btn-warning ml-2" @click="clearGetOutput">Clear</button>
        </div>   
        
        <div v-if="getResult" class="alert alert-secondary mt-2" role="alert"><pre>{{getResult}}</pre></div>
      </div>
    </div>
  </div>
</template>

<script>
const baseURL = "http://localhost:8080/api";

export default {
  name: "App",
  data() {
    return {
      getResult: null
    }
  },
  methods: {
    fortmatResponse(res) {
      return JSON.stringify(res, null, 2);
    },

    async getAllData() {
      try {
        const res = await fetch(`${baseURL}/tutorials`);

        if (!res.ok) {
          const message = `An error has occured: ${res.status} - ${res.statusText}`;
          throw new Error(message);
        }

        const data = await res.json();

        const result = {
          status: res.status + "-" + res.statusText,
          headers: {
            "Content-Type": res.headers.get("Content-Type"),
            "Content-Length": res.headers.get("Content-Length"),
          },
          length: res.headers.get("Content-Length"),
          data: data,
        };

        this.getResult = this.fortmatResponse(result);
      } catch (err) {
        this.getResult = err.message;
      }
    },

    async getDataById() {
      const id = this.$refs.get_id.value;

      if (id) {
        try {
          const res = await fetch(`${baseURL}/tutorials/${id}`);

          if (!res.ok) {
            const message = `An error has occured: ${res.status} - ${res.statusText}`;
            throw new Error(message);
          }

          const data = await res.json();

          const result = {
            data: data,
            status: res.status,
            statusText: res.statusText,
            headers: {
              "Content-Type": res.headers.get("Content-Type"),
              "Content-Length": res.headers.get("Content-Length"),
            },
          };

          this.getResult = this.fortmatResponse(result);
        } catch (err) {
          this.getResult = err.message;
        }
      }
    },

    async getDataByTitle() {
      const title = this.$refs.get_title.value;

      if (title) {
        try {
          // const res = await fetch(`${baseURL}/tutorials?title=${title}`);

          let url = new URL(`${baseURL}/tutorials`);
          const params = { title: title };
          url.search = new URLSearchParams(params);

          const res = await fetch(url);

          if (!res.ok) {
            const message = `An error has occured: ${res.status} - ${res.statusText}`;
            throw new Error(message);
          }

          const data = await res.json();

          const result = {
            status: res.status + "-" + res.statusText,
            headers: {
              "Content-Type": res.headers.get("Content-Type"),
              "Content-Length": res.headers.get("Content-Length"),
            },
            data: data,
          };

          this.getResult = this.fortmatResponse(result);
        } catch (err) {
          this.getResult = err.message;
        }
      }
    },

    clearGetOutput() {
      this.getResult = null;
    },
  }
}
</script>

The result will look like this:

vue-fetch-data-from-api-example

Find tutorial by id:

vue-fetch-data-from-api-example-search

Filter tutorials by title:

vue-fetch-data-from-api-example-filter

Vue Fetch POST example

Let’s use Vue Fetch POST Json data to create new Tutorial.

We use JSON.stringify() on the object before passing it in the body of the request and set:

  • "post" for method
  • "application/json" for the header Content-Type
<template>
  <div id="app" class="container">
    <div class="card">
      <div class="card-header">Vue Fetch POST - BezKoder.com</div>
      <div class="card-body">
        <div class="form-group">
          <input type="text" class="form-control" ref="post_title" placeholder="Title" />
        </div>
        <div class="form-group">
          <input type="text" class="form-control" ref="post_description" placeholder="Description" />
        </div>
        <button class="btn btn-sm btn-primary" @click="postData">Post Data</button>
        <button class="btn btn-sm btn-warning ml-2" @click="clearPostOutput">Clear</button>

        <div v-if="postResult" class="alert alert-secondary mt-2" role="alert"><pre>{{postResult}}</pre></div>
      </div>
    </div>
  </div>
</template>

<script>
const baseURL = "http://localhost:8080/api";

export default {
  name: "App",
  data() {
    return {
      postResult: null
    }
  },
  methods: {
    fortmatResponse(res) {
      return JSON.stringify(res, null, 2);
    },

    async postData() {
      const postData = {
        title: this.$refs.post_title.value,
        description: this.$refs.post_description.value,
      };

      try {
        const res = await fetch(`${baseURL}/tutorials`, {
          method: "post",
          headers: {
            "Content-Type": "application/json",
            "x-access-token": "token-value",
          },
          body: JSON.stringify(postData),
        });

        if (!res.ok) {
          const message = `An error has occured: ${res.status} - ${res.statusText}`;
          throw new Error(message);
        }

        const data = await res.json();

        const result = {
          status: res.status + "-" + res.statusText,
          headers: {
            "Content-Type": res.headers.get("Content-Type"),
            "Content-Length": res.headers.get("Content-Length"),
          },
          data: data,
        };

        this.postResult = this.fortmatResponse(result);
      } catch (err) {
        this.postResult = err.message;
      }
    },

    clearPostOutput() {
      this.postResult = null;
    },
  }
}
</script>

Check the result by making a Fetch Post Request:

vue-fetch-post-example

Vue Fetch example – PUT request

We’re gonna use Vue Fetch with PUT request to update an existing Tutorial.

<template>
  <div id="app" class="container">
    <div class="card">
      <div class="card-header">Vue Fetch PUT - BezKoder.com</div>
      <div class="card-body">
        <div class="form-group">
          <input type="text" class="form-control" ref="put_id" placeholder="Id" />
        </div>
        <div class="form-group">
          <input type="text" class="form-control" ref="put_title" placeholder="Title" />
        </div>
        <div class="form-group">
          <input type="text" class="form-control" ref="put_description" placeholder="Description" />
        </div>
        <div class="form-check mb-2">
          <input type="checkbox" class="form-check-input" ref="put_published" />
          <label class="form-check-label" for="put_published">Publish</label>
        </div>
        <button class="btn btn-sm btn-primary" @click="putData">Update Data</button>
        <button class="btn btn-sm btn-warning ml-2" @click="clearPutOutput">Clear</button>

        <div v-if="putResult" class="alert alert-secondary mt-2" role="alert"><pre>{{putResult}}</pre></div>
      </div>
    </div>
  </div>
</template>

<script>
const baseURL = "http://localhost:8080/api";

export default {
  name: "App",
  data() {
    return {
      putResult: null
    }
  },
  methods: {
    fortmatResponse(res) {
      return JSON.stringify(res, null, 2);
    },

    async putData() {
      const { put_id: id, put_title, put_description, put_published } = this.$refs;

      if (id) {
        const putData = {
          title: put_title.value,
          description: put_description.value,
          published: put_published.checked,
        };

        try {
          const res = await fetch(`${baseURL}/tutorials/${id}`, {
            method: "put",
            headers: {
              "Content-Type": "application/json",
              "x-access-token": "token-value",
            },
            body: JSON.stringify(putData),
          });

          if (!res.ok) {
            const message = `An error has occured: ${res.status} - ${res.statusText}`;
            throw new Error(message);
          }

          const data = await res.json();

          const result = {
            status: res.status + "-" + res.statusText,
            headers: { "Content-Type": res.headers.get("Content-Type") },
            data: data,
          };

          this.putResult = this.fortmatResponse(result);
        } catch (err) {
          this.putResult = err.message;
        }
      }
    },

    clearPutOutput() {
      this.putResult = null;
    },
  }
}
</script>

The result will look like this:

vue-fetch-put-example

Vue Fetch example – DELETE request

Now we implement a Vue component to delete data with Fetch Delete method:

  • delete a Tutorial
  • delete all Tutorials
<template>
  <div id="app" class="container">
    <div class="card">
      <div class="card-header">Vue Fetch DELETE - BezKoder.com</div>
      <div class="card-body">
        <div class="input-group input-group-sm">
          <button class="btn btn-sm btn-danger" @click="deleteAllData">Delete All</button>

          <input type="text" ref="delete_id" class="form-control ml-2" placeholder="Id" />
          <div class="input-group-append">
            <button class="btn btn-sm btn-danger" @click="deleteDataById">Delete by Id</button>
          </div>

          <button class="btn btn-sm btn-warning ml-2" @click="clearDeleteOutput">Clear</button>
        </div>    
        
        <div v-if="deleteResult" class="alert alert-secondary mt-2" role="alert"><pre>{{deleteResult}}</pre></div>      
      </div>
    </div>
  </div>
</template>

<script>
const baseURL = "http://localhost:8080/api";

export default {
  name: "App",
  data() {
    return {
      deleteResult: null
    }
  },
  methods: {
    fortmatResponse(res) {
      return JSON.stringify(res, null, 2);
    },

    async deleteAllData() {
      try {
        const res = await fetch(`${baseURL}/tutorials`, { method: "delete" });

        const data = await res.json();

        const result = {
          status: res.status + "-" + res.statusText,
          headers: { "Content-Type": res.headers.get("Content-Type") },
          data: data,
        };

        this.deleteResult = this.fortmatResponse(result);
      } catch (err) {
        this.deleteResult = err.message;
      }
    },

    async deleteDataById() {
      const id = this.$refs.delete_id.value;

      if (id){
        try {
          const res = await fetch(`${baseURL}/tutorials/${id}`, { method: "delete" });

          const data = await res.json();

          const result = {
            status: res.status + "-" + res.statusText,
            headers: { "Content-Type": res.headers.get("Content-Type") },
            data: data,
          };

          this.deleteResult = this.fortmatResponse(result);
        } catch (err) {
          this.deleteResult = err.message;
        }
      }
    },

    clearDeleteOutput() {
      this.deleteResult = null;
    }
  }
}
</script>

The result could be like this:

vue-fetch-delete-example

Conclusion

With this Vue Fetch example, you’ve known many ways to make GET/POST/PUT/DELETE request using Fetch API (with headers, params, body, form data…) in a Vuejs component.

Instead of Fetch API, you can also use Axios which is a promise-based HTTP Client Javascript library. Kindly visit:
Vue 2 CRUD example with Axios & Vue Router
Vue 3 CRUD example with Axios & Vue Router

Happy Learning! See you again.

Source Code

The complete source code for this tutorial can be found at Github.

Leave a Reply

Your email address will not be published. Required fields are marked *