Reputation: 45
I'm trying to have my Spinner
component show only before the API data is loaded, otherwise, it should be hidden. I created a variable called value
and set it to true
whenever the API info is fetched but I seem to be getting it wrong when using the v-if
and v-else
directives. At the moment only one component is loaded when using the v-if
.
What am I doing wrong?
I'm new to Vue.js and I've seen the directive called v-cloak
but I'm not particularly sure how to use it.
<template lang="">
<div>
<Header />
<Spinner v-if="!value" />
<CryptoList v-else v-bind:crypts="cryptoData" />
</div>
</template>
<script>
import Header from "./components/Header";
import CryptoList from "./components/CryptoList";
import Spinner from "./components/Spinner";
import axios from "axios";
const API_KEY = "ed599676c60cb5b0b369519d8cadaa8a";
export default {
data: function() {
return {
cryptoData: [],
value: null
};
},
name: "App",
components: {
Header,
CryptoList,
Spinner
},
methods: {
isMounted() {
return (this.value = false);
}
},
mounted() {
axios
.get(`https://api.nomics.com/v1/currencies/ticker?key=${API_KEY}`, {
params: {
"per-page": "100",
"page": 1,
"rank": 1
}
})
.then((response) => {
this.cryptoData = response.data;
console.log(response.data);
})
.catch(function(error) {
console.log(error);
});
this.value = true;
console.log(this.value);
}
};
</script>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-size: 16px;
}
body {
font-family: "Baloo 2";
font-weight: lighter;
color: #e7e7de;
background-image: url("./img/background.jpg");
background-repeat: no-repeat;
background-attachment: fixed;
}
</style>
Upvotes: 1
Views: 461
Reputation: 90068
You're setting this.value = true
before the API call returns. You have to do it after:
mounted() {
axios
.get(...)
.then((response) => {
this.cryptoData = response.data;
// <= here the API call returned (you're inside the promise)
this.value = true;
});
// <= here API call has not returned yet. (you're outside the promise)
// you're in mounted, right after the API call was made
}
An alternative approach is to turn value
into a computed
returning true/false
based on current value of cryptoData
's length:
data: () => ({
cryptoData: []
}),
computed: {
value() {
return !!this.cryptoData.length;
}
},
mounted() {
axios
.get(...)
.then((response) => {
this.cryptoData = response.data;
});
}
Whenever you want to show the spinner again, all you have to do is empty cryptoData
:
this.cryptoData = [];
I would also advise you to work on your naming practices (as a general rule, naming variables or properties value
, what
, when
, who
, some
, few
, is considered bad practice). Good practice is using descriptive names, announcing the role or the function performed. In this case, I'd rename value
to hasData
or maybe isLoadingData
. Good coding and naming practices will save you time, money, hair, even jobs.
Upvotes: 1