How do I use API to fetch data for chart in the context of Vuejs - api

I'm new to Vuejs, and I want to make my code effective by fetching the data from API rather than giving the data directly.
Here is my code:
<template>
<canvas id="myChart" width="550" height="300"></canvas>
</template>
<script>
export default {
name: 'Chart',
data: () => ({
arrdate: [
1600934100.0,
1602009600.0,
1602747060.0,
1603050158.390939,
1603305573.992575
],
arrchallenge: [
9.0,
9.5,
2.5,
11.52,
12.4
]
}),
mounted () {
// eslint-disable-next-line no-unused-vars
const data = this.arrdate.map((arrdate, index) => ({
x: new Date(arrdate * 1000),
y: this.arrchallenge[index]
}))
const ctx = document.getElementById('myChart').getContext('2d')
// eslint-disable-next-line no-undef,no-unused-vars
const myChart = new Chart(ctx, {
type: 'line',
data: {
datasets: [
{
data,
label: 'Performance',
borderColor: '#7367F0'
}
]
},
options: {
scales: {
xAxes: [
{
type: 'time',
time: {
unit: 'month',
displayFormats: {
month: 'MMM YYYY'
}
}
}
],
yAxes: [
{
ticks: {
// eslint-disable-next-line no-unused-vars
callback (value, index, values) {
return `${value }%`
}
}
}
]
}
}
})
}
}
</script>
As you can see, the "date" and "challenge" contains data which is fed directly, but I want to fetch data from API.
What my API returns:
{
"date": [
1600934100.0,
1602009600.0,
1602747060.0,
1603050158.390939,
1603305573.992575
],
"challenge": [
9.1
9.5
-2.8
18.52
15.4
]
}
So as you can see my API, I want the "date's" data to be in arrdate and "challenge's" data to be in arrchallenge by using API.
Someone please help me with this, and if someone knows the answer please send me the changes by adding it to my code itself because I'm new to vuejs wrapping the contents would be difficult for me.

first add axios to your project and read the link below from vue documentation:
using axios with vue
after that you have two options:
Call API on page load
with this option your API calls as soon as your vue app loads so in your created hook do the API call like this:
created() {
axios.get('yourAPIUrl').then((response) => {
// reassign date and challenge with the response from the API call here for example:
this.date = response.data.date;
this.challenge = response.data.challenge
});
}
basically what it does is that you call the API when your vue is created and in the then part you use the response to updata the variables defined in your data object.
Call API on button click
with this method you have a button on your page like this:
<button #click="callAPI">get data from server</button>
when you click the button it calls the callAPI method and in your methods you have the same code as before, like this:
methods: {
callAPI() {
// same code as in the created example
}
}
you can also use async ... await syntax for API call if you want to.
also you can read this article on how to install and use axios in your project:
use axios API with vue CLI

I created this API for you to use to test out the solutions provided by anyone:
https://wirespec.dev/Wirespec/projects/apis/Stackoverflow/apis/fetchChartDataForVueJs
And here is the response:
https://api.wirespec.dev/wirespec/stackoverflow/fetchchartdataforvuejs
You can also create your own API on Wirespec and use it to generate more data (sequential or random) if you need more diverse testing.

Related

How Do I Resolve this "An error was captured in current module: TypeError: e.parse is not a function"

How do I solve this Vue Js error on Shopware 6 Administration. The module is suppose to select a column in the database table.
PS. This is the complete code. I'm trying to read data from the database and view it in the twig template.
const { Component, Mixin } = Shopware;
const { Criteria } = Shopware.Data;
import template from './store-settings-page.html.twig'
Component.register('store-settings-page', {
template,
inject: [
'repositoryFactory'
],
metaInfo() {
return {
title: this.$createTitle()
};
},
data: function () {
return {
entity: undefined,
storeData: null,
entityId: '4e2891496c4e4587a3a7efe587fc8c80',
secret_key: 'hdkkjjsmk538dncbjmns',
public_key: '1destinoDet2123lefmoddfk##$$%O',
}
},
computed: {
storeKeysRepository() {
return this.repositoryFactory.create('store_keys');
},
},
created() {
this.storeKeysRepository
.get(this.entityId, Shopware.Context.api)
.then(entity => {
this.entity = entity;
});
console.log(entity);
},
});
Apologies if my knowledge of Vue & JS is a bit off, based on how I see Shopware codes it, I recommend data to be written like this:
data() {
return {
...
};
}
I would also try to strip your file to the bear minimum to see when the error disappears.
Another thing to check is if you are running a JS file or TS file. Maybe it's having a hard time parsing your file because you are extending store-settings-page and it assumes it should be TypeScript?
this.storeKeysRepository
.get(this.entityId, Shopware.Context.api)
.then(entity => {
this.entity = entity;
console.log(this.entity);
});
This will do the trick

How to use Google Map API in Nuxt Js?

This is my code below to fetch API in Nuxt.Js. I have written the code that should be used to call an API, but I am not getting the results. I am not getting any resources regarding this as well.
async created(){
const config = {
headers : {
Accept : "application/json"
}
};
try{
const result = await axios.get(`https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap`, config);
console.warn(result);
//this.users = result.data;
}
catch (err){
console.warn(err);
}
},
Official GM NPM loader + diy Nuxt plugin
There's an official npm loader for the Google Maps JS API:
https://developers.google.com/maps/documentation/javascript/overview#Loading_the_Maps_API
https://www.npmjs.com/package/#googlemaps/js-api-loader
Below is how I have it implemented in Nuxt (2.15.7).
Side note: Yes, this places your API key client side, which in some contexts (e.g. internal team tools) is fine. For public production deployment, you probably want to protect the API key behind a proxy server, and keep any communication with Google occurring only on your server. A proxy server works great for things like Google search and geolocation services, however for map tiles you may never have a map tile server as fast as Google, so you may have to keep an API key on client-side to ensure smooth performance.
1. Install
npm i #googlemaps/js-api-loader
2. Make your own Nuxt plugin
plugins/mapGoogle.client.js
This keeps the Google Map API as a global so you can make use of it in various components (i.e. non-map contexts, like searching Google Places in a form).
import Vue from 'vue'
import { Loader } from '#googlemaps/js-api-loader'
// Store GM_instance as a window object (outside of the Vue context) to satisfy the GM plugin.
window.GM_instance = new Loader({
apiKey: process.env.GOOGLEMAPSAPIKEY, // This must be set in nuxt.config.js
version: "weekly",
libraries: ["places", "drawing", "geometry"] // Optional GM libraries to load
})
Vue.mixin({
data() {
return {
GM_loaded: false, // Tracks whether already GM loaded
GM_instance: null // Holds the GM instance in the context of Vue; much more convenient to use *anywhere* (Vue templates or scripts) whereas directly accessing the window object within Vue can be problematic.
GM_placeService: null, // Optional - Holds the GM Places service
}
},
methods: {
GM_load() {
return new Promise( async (resolve, reject) => {
// Need to do this only once
if (!this.GM_loaded) {
// Load the GM instance
window.GM_instance.load()
.then((response) => {
this.GM_loaded = true
// this.GM_instance is what we use to interact with GM throughout the Nuxt app
this.GM_instance = response
resolve()
})
.catch(e => {
reject(e)
})
} else {
resolve()
}
})
},
// OPTIONAL FUNCTIONS:
GM_loadPlaceService(map) {
this.GM_placeService = new this.GM_instance.maps.places.PlacesService(map)
},
GM_getPlaceDetails(placeRequest) {
return new Promise((resolve, reject) => {
this.GM_placeService.getDetails(placeRequest, (response) => {
resolve(response)
})
})
}
}
})
3. Set env and plugin in nuxt config
nuxt.config.js
Pass your GM key from your .env file and register your new plugin.
export default {
// ...
// It's best to keep your GM key where all other keys are: your .env file; however this is inaccessible client-side.
// Here, we tell Nuxt the specific env's we want to make available client-side.
env: {
GOOGLEMAPSAPIKEY: process.env.GOOGLEMAPSAPIKEY
},
// Register your new plugin
plugins: [
'#/plugins/mapGoogle.client.js',
],
// ...
}
4. Now use the GM plugin anywhere
components/map.vue
Make a map and process clicks on Google Places
<template>
<div id="map" class="map"></div>
</template>
<script>
export default {
name: "MapGoogle",
data() {
return {
map: null
}
},
mounted() {
// This is the actual trigger that loads GM dynamically.
// Here we run our global GM func: GM_load.
// Side note; annoyance: As you see, using Vue mixin's, you have functions available from out-of-nowhere. Research alternative to mixin's, especially in Vue3/Nuxt3.
this.GM_load()
.then( () => {
this.initMap()
})
},
methods: {
initMap() {
this.map = new this.GM_instance.maps.Map(document.getElementById("map"), {
center: { lat: 43.682284, lng: -79.401603 },
zoom: 8,
})
this.GM_loadPlaceService(this.map)
this.map.addListener("click", (e) => {
this.processClick(e)
})
}
},
async processClick(e) {
// If clicked target has a placeId, user has clicked a GM place
if (e.placeId) {
let placeRequest = {
placeId: e.placeId,
//fields: ['name', 'rating', 'formatted_phone_number', 'geometry']
}
// Get place details
let googlePlace = await this.GM_getPlaceDetails(placeRequest)
console.log("googlePlace %O", googlePlace)
}
}
}
</script>

Cannot use Maps JavaScript API on vue (nuxt)

here is code that i try
head: {
script: [
{
src: "https://maps.googleapis.com/maps/api/js?key=MYKEY&libraries=places&callback=initAutocomplete",
},
],
},
mounted() {
new google.maps.places.Autocomplete(
document.getElementById('autocomplete')
)
},
And i got this error
Thanks for any help
When you go to import the googlemaps scripts it is not said that the script has already been loaded.
The best thing is to put a global hook and then emit an event like maybe an eventHub.
Example of event hub https://www.digitalocean.com/community/tutorials/vuejs-global-event-bus
//your mapsPlugin.js
import eventHub from "./your-event-hub";
window.initAutocomplete = () => {
eventHub.$emit("maps-loaded");
};
mounted() {
// mounted of your component
eventHub.$on("maps-loaded", () => {
// your stuff
});
},
You can try:
Introduced in the index.html page
<script src="https://maps.googleapis.com/maps/api/js?key=MYKEY&libraries=places&callback=initAutocomplete"></script>
new google.maps.places.Autocomplete() change into new window.google.maps.places.Autocomplete();

TypeError: Cannot read property 'cache' of undefined - VueJS

I created a Vue component which exports an async function. This component acts as a wrapper for calling my API. It's based on axios with a caching component that relies on localforage for some short lived persistence.
import localforage from 'localforage'
import memoryDriver from 'localforage-memoryStorageDriver'
import { setup } from 'axios-cache-adapter'
export default {
async cache() {
// Register the custom `memoryDriver` to `localforage`
await localforage.defineDriver(memoryDriver)
// Create `localforage` instance
const store = localforage.createInstance({
// List of drivers used
driver: [
localforage.INDEXEDDB,
localforage.LOCALSTORAGE,
memoryDriver._driver
],
// Prefix all storage keys to prevent conflicts
name: 'tgi-cache'
})
// Create `axios` instance with pre-configured `axios-cache-adapter` using a `localforage` store
return setup({
// `axios` options
baseURL: 'https://my.api',
cache: {
maxAge: 2 * 60 * 1000, // set cache time to 2 minutes
exclude: { query: false }, // cache requests with query parameters
store // pass `localforage` store to `axios-cache-adapter`
}
})
}
}
Here is how I am importing and using this component in my views:
import api from '#/components/Api.vue'
export default {
data() {
return {
userId: this.$route.params.id,
userData: ''
}
},
methods: {
loadClient(userId) {
const thisIns = this;
api.cache().then(async (api) => {
const response = await api.get('/client/find?id='+userId)
thisIns.userData = response.data.data[0]
}).catch(function (error) {
console.log(error)
})
},
},
created() {
this.loadClient(this.userId)
},
}
I can import this component and everything appears to work. I get data back from my API. However, immediately after every call, I get an error:
TypeError: Cannot read property 'cache' of undefined
Which references this line:
api.cache().then(async (api) => {
I am unable to understand why this is happening, or what it means. The error itself indicates that the component I am importing is undefined, though that's clearly not the case; if it were, the API call would ultimately fail I would suspect. Instead, I am lead to believe that perhaps I am not constructing/exporting my async cache() function properly.
Upon further review, I don't actually understand why the author has implemented it the way he has. Why would you want to create an instance of localForage every single time you make an API call?
I've opted not to use a component and to only instantiate an instance of localForage once.
main.js
import localforage from 'localforage'
import memoryDriver from 'localforage-memoryStorageDriver'
import { setup } from 'axios-cache-adapter'
// Register the custom `memoryDriver` to `localforage`
localforage.defineDriver(memoryDriver)
// Create `localforage` instance
const localforageStore = localforage.createInstance({
// List of drivers used
driver: [
localforage.INDEXEDDB,
localforage.LOCALSTORAGE,
memoryDriver._driver
],
// Prefix all storage keys to prevent conflicts
name: 'my-cache'
})
Vue.prototype.$http = setup({
baseURL: 'https://my.api',
cache: {
maxAge: 2 * 60 * 1000, // set cache time to 2 minutes
exclude: { query: false }, // cache requests with query parameters
localforageStore // pass `localforage` store to `axios-cache-adapter`
}
})
the view
export default {
data() {
return {
userId: this.$route.params.id,
userData: ''
}
},
methods: {
loadClient(userId) {
const thisIns = this;
thisIns.$http.get('/client/find?id='+userId)
.then(async (response) => {
thisIns.userData = response.data.data[0]
})
.catch(function (error) {
console.log(error)
})
},
},
created() {
this.loadClient(this.userId)
},
}

Prop not Reactive using VUE to send configuration

I have started learning Vue and came quite far :) but still consider myself beginner. I have bought a vue based single page application template
Themeforest Template Link
I am building my application over it and it uses FlatPickr
I am trying to use FlatPickr's enable functionality
{
enable: ["2025-03-30", "2025-05-21", "2025-06-08", new Date(2025, 8, 9) ]
}
I asked the developer how to use this as it was not in instructions so he replied:
you can use the config prop to pass all Flatpickr options.
I have codes which looks like this
<c-flatpickr
v-validate="'required'"
v-model="dateRange"
:config="enabledDates"
name="Select Date Range"
value="" range
/>
enabledDates: function (){
var data = this.trip.tripsDetails;
var options = {
enable: [],
};
for (let i in data){
options.enable.push(data[i].startingDate);
}
return options;
},
my problem is if I pass the data statically it works so if I put values in array manually like
var options = {
enable: ['01-06-2018', '03-06-2018', '06-06-2018'],
};
it works but if I try to push values dynamically (as per my codes above) it doesn't work.
What am I doing wrong?
Thanks for your help in advance.
// Here are the codes
data() {
return {
trip: new Form({
//All Trips
tripsDetails: [],
}),
dateRange: undefined,
}
},
methods: {
getData(pageid){
this.trip.tripsDetails = [];
axios
.get('/trip/getTrips',{
params: {
equipment_id : this.trip.equipment_id,
dispatch_id: this.pageid
}
})
.then(response => {
this.trip.tripsDetails = response.data.data;
this.loading();
}).catch(error => {
this.loading();
this.errortoast();
});
},