How to update a vue ChartJS? - javascript

Hello I would like to understand how to update my vue.chart.js. I make a GET request every 1 second and I would like to be able to update the display to show the latest value. But I don't see how to do it.
Does anyone know how to do it?
Here is my code :
<template>
<div>
<v-col>
<v-card class="mx-auto" v-if="this.arrTemperature.length > 0">
<v-card-title class="text-h6 font-weight-black">Température</v-card-title>
<line-chart ref="chartTemp" :chartData="arrTemperature" :options="chartOptions" :chartColors="blueChartColors"
label="Température" />
</v-card> <br>
</v-col>
</div>
</template>
<script>
import LineChart from "../components/LineChart";
import moment from "moment";
export default {
components: {
LineChart,
},
data() {
return {
arrTemperature: [],
// =============================== CHART TEMPERATURE ===============================
mounted(){
setInterval(this.getTemperature, 1000)
},
methods: {
async getTemperature() {
const tag_id = encodeURIComponent('bts_d02c2b7d9098aaa2');
const url = this.$api.getRESTApiUri() + `/temperature/last_id/${tag_id}`;
return fetch(url)
.then(res => res.text())
.then((result) => {
const data = JSON.parse(result);
data.forEach(d => {
let date = moment(d.time).format("DD-MM-YYYY HH:mm:ss");
const {
temperature,
} = d;
this.arrTemperature.push({
date,
y: data[0].temperature
});
console.log(date)
console.log(data[0].temperature)
this.ChartData = { ...this.arrTemperature }
});
})
.catch((error) => {
console.log(error)
});
},
}
};
</script>
here is my display:

Related

How to get json data out of a scope after fetching data in Vue?

I'm new to Vue, javascript & Web development. Using Vue, I tried to recreate the moviedb app(from Brad's 50 JS Projects in 50 Days course).
I'm getting stuck and can't get the data out of a scope.
I've successfully retrieved data & destructured it.
But how can I get those values out of that scope (out of setMovies function) and use it in the Vue file (html template)?
Here's my code:
I've made the api_key private
<h1>MovieDesk</h1>
<div class="hero">
<!-- Search -->
<div class="search">
<form #submit.prevent="handleSearch">
<input type="text" placeholder="Search here..." />
<button #click="handleSearch">Search</button>
</form>
</div>
</div>
<!-- Movies -->
<div v-if="searchOn">
<SearchedMovies />
</div>
<div v-else>
<MovieList/>
</div>
</template>
<script>
// imports-------------------
import { ref } from "#vue/reactivity";
import MovieList from "../components/MovieList.vue";
import SearchedMovies from "../components/SearchedMovies.vue";
import { onMounted } from "#vue/runtime-core";
export default {
components: { MovieList, SearchedMovies },
setup() {
const searchOn = ref(false);
const api_url = ref(
"https://api.themoviedb.org/3/discover/movie?sort_by=popularity.desc&api_key=api_key&page=1"
);
const movies = ref([])
// getting the data ------------------------------
onMounted(() => {
fetch(api_url.value)
.then((res) => res.json())
.then((data) => {
console.log(data);
setMovies(data.results);
});
});
function setMovies(movies) {
movies.forEach((movie) => {
const { title, poster_path, vote_average, overview } = movie;
});
}
return { searchOn, setMovies };
},
};
</script> ```
In your setMovies function, You can set the response in the movies variable and then return that variable from your setup.
function setMovies(apiResponse) {
movies.value = apiResponse
}
return { movies };
Live Demo :
const { ref, onMounted } = Vue;
const App = {
setup() {
const movies = ref([])
onMounted(() => {
const apiResponse = [{
id: 1,
name: 'Movie 1'
}, {
id: 2,
name: 'Movie 2'
}, {
id: 3,
name: 'Movie 3'
}];
setMovies(apiResponse);
})
function setMovies(res) {
movies.value = res;
}
return {
movies
};
}
};
Vue.createApp(App).mount("#app");
<script src="https://unpkg.com/vue#next"></script>
<div id="app">
<pre>{{ movies }}</pre>
</div>
Add 'movies' to the return statement at the bottom of your code, then you should be able to render it.

How to update a Vue-ChartJs?

I'm trying to update my line chart using vue chart js.
Each 1 second I'm making a get request do a datatable and I would like to be able to update my chart so I can display the last data but i can't figure how to do it.
I tried computed properties but nothing change..
Here is my code chart.vue :
<template>
<div>
<v-col>
<v-card class="mx-auto" v-if="this.arrTemperature.length > 0">
<v-card-title class="text-h6 font-weight-black">Température</v-card-title>
<line-chart ref="chartTemp" :chartData="chartData" :options="chartOptions" :chartColors="blueChartColors"
label="Température" />
</v-card> <br>
</v-col>
</div>
</template>
<script>
import LineChart from "../components/LineChart.js";
import moment from "moment";
export default {
components: {
LineChart,
},
data() {
return {
arrTemperature: [],
},
};
},
mounted(){
setInterval(this.getTemperature, 1000)
},
computed:{
chartData(){return this.arrTemperature} //where it is supposed to update the datas
},
methods: {
async getTemperature() {
const tag_id = encodeURIComponent('bts_d02c2b7d9098aaa2');
const url = this.$api.getRESTApiUri() + `/temperature/last_id/${tag_id}`;
return fetch(url)
.then(res => res.text())
.then((result) => {
const data = JSON.parse(result);
data.forEach(d => {
let date = moment(d.time).format("DD-MM-YYYY HH:mm:ss");
const {
temperature,
} = d;
this.arrTemperature.push({
date,
value: temperature
});
console.log(date)
console.log(temperature)
let n = JSON.parse(JSON.stringify(this.arrTemperature));
console.log(n)
});
})
.catch((error) => {
console.log(error)
});
},
}
};
</script>
Here my LineChart.js :
import { Line,} from "vue-chartjs";
export default {
extends: Line,
props: {
chartData: {
type: Array
},
},
mounted() {
const dates = this.chartData.map(d => d.date);
const value = this.chartData.map(d => d.value);
this.renderChart({
labels: dates,
datasets: [{
label: this.label,
data: value,
fill: false,
tension: 0.4
}]
},
);
},
};

Issue with Api call, not returning any response in Vuejs?

import axios from "axios";
export const routerid = (itemId) =>
axios.get("https://fakestoreapi.com/products?limit=" + itemId);
<template>
<div>
<div v-for="(item, key) in user" :key="key">
{{ item.price }} <br />
{{ item.description }} <br />
</div>
</div>
</template>
<script>
import { routerid } from "./routerid";
export default {
name: "User",
components: {},
data() {
return {
lists: [],
};
},
mounted() {
if (this.$route.params.id)
routerid(this.$route.params.id).then((r) => {
let obj = r.data;
this.lists = [{ ...obj }];
});
},
computed: {
user: function () {
return this.lists.filter((item) => {
return item.id === this.$route.params.id;
});
},
},
};
</script>
How to make axios url call with query params like this..https://fakestoreapi.com/products?limit=1 Where you can see in the url i have ...like ?limit=id.... So i am little bit confused about it..How to call
Did i correctly call the api or anything missing in the code logic. As of now, In my output, I cant see any response from the api.
Code:- https://codesandbox.io/s/cocky-ives-h19zm7?file=/src/components/routerid.js
Don't you want to fetch a product by its ID?
Then it rather would be:
export const routerid = async (itemId) =>
await axios.get("https://fakestoreapi.com/products/" + itemId);
https://codesandbox.io/s/silly-nightingale-ixz8tr

bind a promise to component in Vue

App.vue
<template>
<v-app>
<v-main>
<Header :token="token" :users="users"/>
<router-view/>
</v-main>
</v-app>
</template>
<script>
import Header from './components/layout/Header'
import axios from 'axios';
export default {
name: 'App',
components: {
Header
},
data() {
return { token: null, users: [] };
},
created(){
this.token = this.getToken();
this.users = this.getUsers();
},
methods:{
getToken(){
axios.get("http://someURL.com")
.then(res => {
console.log("token = ", res)
return res;
});
},
getUsers(){
axios.get("http://someURL.com")
.then(res => {
let users = res.data.map(({username}) => username);
console.log("users = ", users)
return users;
});
}
}
};
</script>
Header.vue
<template>
<header class="header">
<v-toolbar dark>
<h1>TITLE</h1>
<v-spacer></v-spacer>
<div>
<router-link to="/">Home</router-link> |
<router-link to="/about">About</router-link>
</div>
</v-toolbar>
<p v-if="users">{{users}}</p>
<p v-else>No Data</p>
</header>
</template>
<script>
export default {
name:"Header",
props: ['token', 'users'],
data: () => ({
}),
mounted(){
this.onStart();
},
methods:{
onStart(){
console.log("insideHeader = ", this.users)
}
}
}
</script>
<style scoped>
#nav{
float: right;
}
.header a{
color: #fff;
padding-right: 5px;
text-decoration: none;
}
</style>
So basically what my problem is, I am fetching some data on App.vue using axios, then binding that data on Header.vue, So when the app loads first the binded value will be undefined, only after some time the data is fetched from API. But even then the value remains undefined in Header. Any solutions?
Api calls are async in nature. hence make use of async/await..
<template>
<v-app>
<v-main>
<Header :token="token" :users="users"/>
<router-view/>
</v-main>
</v-app>
</template>
<script>
import Header from './components/layout/Header'
import axios from 'axios';
export default {
name: 'App',
components: {
Header
},
data() {
return { token: null, users: [] };
},
async created(){
this.token = await this.getToken();
this.users = await this.getUsers();
},
methods:{
getToken(){
return axios.get("http://someURL.com")
.then(res => {
console.log("token = ", res)
return res.data;
});
},
getUsers(){
return axios.get("http://someURL.com")
.then(res => {
let users = res.data.map(({username}) => username);
console.log("users = ", users)
return users;
});
}
}
};
</script>
Don't try to return a value from promise callback, you could use async/await to return the response :
<template>
<v-app>
<v-main>
<Header :token="token" :users="users"/>
<router-view/>
</v-main>
</v-app>
</template>
<script>
import Header from './components/layout/Header'
import axios from 'axios';
export default {
name: 'App',
components: {
Header
},
data() {
return { token: null, users: [] };
},
created(){
this.token = this.getToken();
this.users = this.getUsers();
},
methods:{
async getToken(){
let res=await axios.get("http://someURL.com")
console.log("token = ", res)
return res.data;
},
async getUsers(){
let res=await axios.get("http://someURL.com")
let users = res.data.map(({username}) => username);
console.log("users = ", users)
return users;
}
}
};
</script>

How do I call Axios on prop change in Vue?

On the change of the value id, I would like to make a JSON call via Axios and update necessary parts of the page. How do I do that? Currently, I have mounted and activated and they do not seem to be working...
Code:
const Home = {
template: `
<div class="user">
<h2>user {{ id }}</h2>
<h2>{{ info }}</h2>
bet
</div>
`,
props: {
id: {
type: String,
default: 'N/A'
}
},
data () {
return {
info: null
}
},
activated () {
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json',
{ params: { id: id }}
)
.then(response => (this.info = response))
},
mounted() {
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => (this.info = 'response'))
}
}`
You can listen to id prop change by using watch:
watch: {
id: function(newId) {
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json',
{ params: { id: newId }}
)
.then(response => (this.info = response))
}
}
Here is a little demo based on the code that you shared that shows how watch reacts to id prop change. Wrapper component below is solely for demonstration purpose as something that triggers id value change.
const Home = {
template: `
<div class="user">
<h2>user {{ id }}</h2>
<h2>{{ info }}</h2>
bet
</div>
`,
props: {
id: {
default: 'N/A'
}
},
data () {
return {
info: null
}
},
mounted() {
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json')
.then(response => (this.info = 'response'))
},
watch: {
id: function(newId) {
console.log(`watch triggered, value of id is: ${newId}`);
axios
.get('https://api.coindesk.com/v1/bpi/currentprice.json',
{ params: { id: newId }}
)
.then(response => (this.info = response))
}
}
}
const Wrapper = {
template: '<div><home :id="id" /></div>',
components: { Home },
data() {
return {
id: 0
}
},
mounted() {
const limit = 5;
const loop = (nextId) => setTimeout(() => {
console.log(`#${nextId} loop iteration`);
if (nextId < limit) {
this.id = nextId;
loop(nextId + 1);
}
}, 3000);
loop(this.id);
}
}
new Vue({
el: '#app',
components: { Wrapper }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/axios/0.18.0/axios.min.js" ></script>
<div id="app">
<wrapper />
</div>

Categories

Resources