Daina Hodges
Daina Hodges

Reputation: 853

Fetch data with Vue from Web API

I have a Web API and I'm trying to get JSON Data from it by using Vue, but I get neither data or errors, so I don't what is wrong. I want to load the data when the page is loaded.

Here is my code:

const v = new Vue({
    el: '#divContent',
    ready: function () {
        this.loadData();
    },
    data: {
        content: 'loading',
        serverData: null
    },
    methods: {
        loadData: function (viewerUserId, posterUserId) {
            const that = this;
            $.ajax({
                contentType: "application/json",
                dataType: "json",
                url: "http://my-webapi/",
                method: "Post",
                success: function (response) {                        
                    that.$data.serverData = response;

                },
                error: function () {
                    alert('Error')
                }
            });
        }
    }
});

My HTML

<div id="divContent" class="content">
 {{ content }}
</div>

Upvotes: 4

Views: 16961

Answers (4)

Yuci
Yuci

Reputation: 30109

Yes you can use jQuery’s $.ajax() API. However, using jQuery just for making Ajax calls is not recommended. You don’t want to include the whole jQuery library just for the purpose of using Ajax, do you? :-)

For Vue.js, you have quite a few options for using Ajax, such as:

Here is an example of using the Browser's fetch API.

HTML

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
  <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>  
</head>
<body>
  <div id="divContent">
    <h1>Article Search Results</h1>
    <form v-on:submit.prevent="search">
      <input type="text" v-model="query">
      <button type="submit">Search</button>
    </form>

    <ul>
    <li v-for="article in articles" v-bind:key="article.source + article.id">
      {{ article.title }}
    </li>
    </ul>
  </div>
</body>
</html>

JavaScript

const vm = new Vue({
  el: '#divContent',
  data() {
    return {
      query: 'gene',
      articles: 'loading'
    }
  },
  created() {
    this.search();
  },
  methods: {
    search: function () {
      fetch(`https://www.ebi.ac.uk/europepmc/webservices/rest/search?query=${this.query}&format=json`)
        .then(response => response.json())
        .then(json => {
          this.articles = json.resultList.result;
      });
    }
  }
});

Output

enter image description here

Upvotes: 7

Bert
Bert

Reputation: 82459

You appear to already be using jQuery, so to load the Vue when the page is loaded you can update your code to the following:

$(function(){
  const v = new Vue({
    el: '#divContent',
    created: function () {
      this.loadData();
    },
    data: {
      content: 'loading',
      serverData: null
    },
    methods: {
      loadData: function (viewerUserId, posterUserId) {
        const that = this;
        $.ajax({
          contentType: "application/json",
          dataType: "json",
          url: "http://my-webapi/",
          method: "Post",
          success: response => this.serverData = response,
          error: err => alert('Error')
        });
      }
    }
  });  
})

The syntax above is using the jQuery.ready shorthand to create the Vue only after the page is loaded.

Without jQuery, you might want to listen for the DOMContentLoaded event.

Alternatively, just load the script that creates the Vue at the bottom of the page and not in the header.

Here is a complete, working example.

console.clear()

$(function(){
  const v = new Vue({
    el: '#divContent',
    created: function () {
      this.loadData();
    },
    data: {
      content: 'loading',
      serverData: null
    },
    methods: {
      loadData: function (viewerUserId, posterUserId) {
        $.ajax({
          contentType: "application/json",
          dataType: "json",
          url: "https://httpbin.org/post",
          data: JSON.stringify({testing: "some value"}),
          method: "Post",
          success: response => {
            this.content = "loaded"
            this.serverData = response.json
          },
          error: err => console.log('Error')
        });
      }
    }
  });  
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.9/vue.js"></script>
<div id="divContent" class="content">
  {{ content }}
  <hr>
  Response: <br>
  {{ serverData }}
</div>

Upvotes: 2

samayo
samayo

Reputation: 16495

Anything your put inside methods: {} won't work unless you call loadData() with @click on the element or when page loads.

So, you should call it on the element or using either created/mount methods:

So, in your case either do this.

<div id="divContent" class="content" @click='loadData'>

or call the method when the page loads as:

created () {
 this.loadData()
}

Upvotes: 1

Daksh M.
Daksh M.

Reputation: 4817

For Loading it on the page load, you can do the following:

const v = new Vue({
    el: '#divContent',
    data: {
        content: 'loading',
        serverData: null
    },
    methods: {
        loadData(viewerUserId, posterUserId) {
            $.ajax({
                contentType: "application/json",
                dataType: "json",
                url: "http://my-webapi/",
                method: "POST",
                success: function (response) { 
                    this.content = 'loaded';                       
                    this.serverData = response;

                },
                error: function () {
                    alert('Error')
                }
            });
        }
    },
    mounted() {
       this.loadData()
    }
});

Upvotes: 0

Related Questions