-1

I'm learning how to use an API with VueJS. I took open source API data on Rapidapi.

I tried with Postman by entering the link https://covid-19-data.p.rapidapi.com/report/country/name?name=Italy&date=2020-04-01, and got a response.

But when trying in VueJS, the data does not appear. Is there any miss in my looping?

Here is a hosted codesandbox of my code: https://codesandbox.io/s/nice-rain-45j6y

<template>
  <div v-for="post in posts" :key="post.id">
    {{ post.country }}
    {{ post.confirmed }}
  </div>
</template>

<script>
export default {
  data() {
     return {}
  },
  computed: {
    posts() {
        return this.$store.state.posts
    }
  },
  mounted() {
    this.$store.dispatch("loadPosts");
  }
};
</script>
import axios from 'axios'

const options = {
    method: 'GET',
    url: 'https://covid-19-data.p.rapidapi.com/country',
    params: {name: 'italy'},
    headers: {
      'x-rapidapi-key': '1031599022msh37c84da8c4e9b0ap1047d6jsn4d6475b64dc7',
      'x-rapidapi-host': 'covid-19-data.p.rapidapi.com'
    }
  };

const covid = {
    state: () => ({
      posts: []
    }),
    mutations:{
      setPosts(state, components){
         state.posts = posts
      }
    },
    actions: {
      loadPosts({ commit }) {
        axios.request(options)
        .then(response => {
            commit('setPosts', response.data)
            console.log(response.data)
        })
        .catch(function (error) {
            console.error(error);
        });
      }
    },

}

export default covid;

The response that I get with my console.log(response.data) is the following

enter image description here

kissu
  • 40,416
  • 14
  • 65
  • 133
Frauds
  • 127
  • 1
  • 3
  • 14
  • When I try it on Postman I also get a response… which is a 401 with the message `"message": "Invalid API key. Go to https://docs.rapidapi.com/docs/keys for more info."`. I don't understand why you are surprised axios gives you a similar error. – Quentin Apr 20 '21 at 07:42
  • where should i put the api key? @Quentin – Frauds Apr 20 '21 at 07:44
  • I've no idea. Try reading the documentation for the service. – Quentin Apr 20 '21 at 07:44
  • You probably need some kind of authentication here, hence the 401. – kissu Apr 20 '21 at 07:50
  • I've changed my code above, and got a response in console. but why does not appear in the vue js template @kissu – Frauds Apr 20 '21 at 07:53
  • It does not appear in the template magically if you do not handle the error in the catch. By that, I mean that you're template is expecting to loop on some posts but if there is none, the template is not clever enough (and should not btw) to handle HTTP error codes. – kissu Apr 20 '21 at 08:02
  • then, how should it be? @kissu – Frauds Apr 20 '21 at 08:04
  • Handling the error is one thing. The other (looping on the results that you got from the backend) is another one. I'm not sure if you needed Vuex here, but you can use it for the result. You could use `
    {{ posts}}
    ` to see if you have the proper object. So far, what I see is that you are missing an `id` in the API response, hence you `:key` cannot be found, maybe replace it with a `:key="post.longitude"` just for now. But the rest should work.
    – kissu Apr 20 '21 at 08:15
  • Also, prefer doing API calls in the `created()` hook, rather than in `mounted()`. – kissu Apr 20 '21 at 08:17
  • Answered it here @Frauds. – kissu Apr 20 '21 at 08:40
  • still not appear @kissu – Frauds Apr 20 '21 at 08:47
  • What does it mean ? What do you have in the `pre` tags ? – kissu Apr 20 '21 at 08:48
  • I could help but you really need to give us some [repro] because I don't feel cloning your configuration myself. Host your code on codesandbox or alike please. Also, please provide full code in your snippet since here, there is not context if your looping div is the only one in the template (it shouldn't because of the one div root limitation). – kissu Apr 20 '21 at 08:54
  • this is my codesandbox https://codesandbox.io/s/nice-rain-45j6y @kissu – Frauds Apr 20 '21 at 10:25
  • Found out a solution and posted an answer. As a side not, you should regenerate a new `x-rapidapi-key` once you've done fixing your issues because you exposed this one to the Internet, hence it's not private now. So, just generate a new one and you should be good ! – kissu Apr 20 '21 at 10:48

2 Answers2

2

It seems you need API key to use it. The code 401 means unauthorized probably because you are not using a key. You can get your API key and add it in the query parameter. You can read the documentation here:

https://docs.rapidapi.com/docs/keys

https://example.p.rapidapi.com/?rapidapi-key=***************************

In your case should be something like:

https://covid-19-data.p.rapidapi.com/report/country/name?name=Italy&date=2020-04-01&rapidapi-key=API_KEY_HERE

EDIT If you want use states in components you need import them.

import { mapState } from 'vuex';

export default{

computed: { ...mapState(['posts']) }
}

You can do the same with actions. http://vuex.vuejs.org/guide/actions.html#dispatching-actions-in-components

alpachino
  • 79
  • 5
  • I've changed my code above, and got a response in console. but why does not appear in the vue js template – Frauds Apr 20 '21 at 07:53
  • Is showing an error? When you use vuex you need import states, actions ... in your components. I have updated my response – alpachino Apr 20 '21 at 08:07
  • Please edit your answer rather than posting inline code in comments. The way he is importing his state is fine tho. As explained in the docs: https://vuex.vuejs.org/guide/state.html#getting-vuex-state-into-vue-components Even if I do recommend using the helpers too. ^^ – kissu Apr 20 '21 at 08:15
  • I've changed my computed as you wrote above, but nothing appears. And I want to ask, where does the computed ```posts``` come from? – Frauds Apr 20 '21 at 08:24
  • if I am correct in importing the state, why doesn't the response appear when looping? @kissu – Frauds Apr 20 '21 at 08:25
  • If I understand it, your problem is you have the post well, with all your data in the component but you can not print it in the for? – alpachino Apr 20 '21 at 08:29
  • 1
    OP should especially install the devtools for VueJS v2 here: https://chrome.google.com/webstore/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd?hl=en That way, he will be able to inspect the array of the response in his state (vuex tab). – kissu Apr 20 '21 at 08:43
1

Thanks to your codesandbox, I achieved to display it properly with this

<template>
  <div>
    <div v-for="post in posts" :key="post.longitude"> <!-- be careful here, you had a longatitude typo here -->
      <div>country: {{ post.country }}</div>
      <div>code: {{ post.code }}</div>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {}
  },
  computed: {
    posts() {
      return this.$store.state.covid.posts
    },
  },
  mounted() {
    this.$store.dispatch('loadPosts')
  },
}
</script>

The main error was essentially in the covid.js file actually

mutations: {
  setPosts(state, posts) { // was components here, but should be posts as the 2nd argument
    state.posts = posts;
  }
},
kissu
  • 40,416
  • 14
  • 65
  • 133
  • ```posts() { return this.$store.state.covid.posts },``` Does the after state have to be the file name in the module?? – Frauds Apr 20 '21 at 10:57
  • You do have a `const covid = { state: () => ...` object in the module, so you need to access it like this in your example yeah. Meanwhile, usually you can only have the objects at the root of the file (not nested) and export them like `export const yourFancyModule = { namespaced: true, state, getters, mutations, actions}`. Then import it in the main store file. – kissu Apr 20 '21 at 12:10