"How to plot the data on the Scatterplots using apexcharts" - javascript

I am using apexchart library in Vue.js to plot the data on scatterplots. I am getting the data from the backend by using Python and Flask. I am able to get the data from the back end to the front end, but The scatterplot is not displaying anything and also there are no errors on the console. My expected result should be the scatterplot containing all the coordinate value which I get from the Backend, i.e. my .py file.
<template>
<div>
<div id="chart">
<apexchart type=scatter height=350 :options="chartOptions" :series="series" />
</div>
<div>
<p> {{ df }} </p>
</div>
</div>
</template>
<script>
import axios from 'axios';
import VueApexCharts from 'vue-apexcharts';
import Vue from 'vue';
Vue.use(VueApexCharts)
Vue.component('apexchart', VueApexCharts)
export default {
data: function() {
return {
df: [],
chartOptions: {
chart: {
zoom: {
enabled: true,
type: 'xy'
}
},
xaxis: {
tickAmount: 3,
},
yaxis: {
tickAmount: 3,
}
},
series: [{
name: 'series-1',
data: [[]]
}],
}
},
methods: {
getPoints() {
const path='http://localhost:5000/scatter';
axios.get(path)
.then((res) => {
this.df=res.data;
console.log(this.df)
})
.catch((error) => {
console.error(error);
});
},
},
created(){
this.getPoints();
},
};
</script>
#Backeend (.py file)
from flask import Flask, jsonify, request
from flask_cors import CORS
app = Flask(__name__)
app.config.from_object(__name__)
#app.route('/scatter',methods=['GET'])
def get_points():
return jsonify([[2, 3], [1, 5]])
Results which I am getting on the Browser

The df prop in which you are assigning your data is not used as the chart's series.data.
Initially, you are putting a blank array in series.data, but after getting data, it seems you are not updating this array. Hence, you might be seeing a blank chart.
Try updating your getPoints method to this
getPoints() {
const path='http://localhost:5000/scatter';
axios.get(path)
.then((res) => {
this.series = [{
data: res.data
}]
})
.catch((error) => {
console.error(error);
});
}

Related

How to create Paypal Button in Vue 3 script setup?

The paypal developer docs show how to implement the Paypal Button into Vue.js but I don't understand the code. At this point I'm not even sure if this is vue 2 or vue 3 or angular?? code.
1: import script in parent blade:
<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID"></script>
2: use button in script tag of component?
paypal.Buttons.driver("vue", window.Vue);
3: this is where I get lost, use this in app.js??:
#ng.core.Component({
selector: 'my-app',
template:
<div id="app">
<paypal-buttons [props]="{
createOrder: createOrder,
onApprove: onApprove
}"></paypal-buttons>
</div>
,
})
class AppComponent {
createOrder(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
value: '0.01'
}
}]
});
}
onApprove(data, actions) {
return actions.order.capture();
}
}
#ng.core.NgModule({
imports: [
ng.platformBrowser.BrowserModule,
paypal.Buttons.driver('angular2', ng.core)
],
declarations: [
AppComponent
],
bootstrap: [
AppComponent
]
})
class AppModule {}
ng.platformBrowserDynamic
.platformBrowserDynamic()
.bootstrapModule(AppModule);
Could it be that this isn't even vue code but angular code?
4: and put this in the vue component??:
<div id="container">
<app></app>
</div>
<script>
const PayPalButton = paypal.Buttons.driver("vue", window.Vue);
Vue.component("app", {
// The style prop for the PayPal button should be passed in as `style-object` or `styleObject` to avoid conflict with Vue's `style` reserved prop.
template: `
<paypal-buttons :on-approve="onApprove" :create-order="createOrder" :on-shipping-change="onShippingChange" :on-error="onError" :style-object="style" />
`,
components: {
"paypal-buttons": PayPalButton,
},
computed: {
createOrder: function () {
return (data, actions) => {
return actions.order.create({
purchase_units: [
{
amount: {
value: "10",
},
},
],
});
}
},
onApprove: function () {
return (data, actions) => {
return actions.order.capture();
}
},
onShippingChange: function () {
return (data, actions) => {
if (data.shipping_address.country_code !== 'US') {
return actions.reject();
}
return actions.resolve();
}
},
onError: function () {
return (err) => {
console.error(err);
window.location.href = "/your-error-page-here";
}
},
style: function () {
return {
shape: 'pill',
color: 'gold',
layout: 'horizontal',
label: 'paypal',
tagline: false
}
},
},
});
const vm = new Vue({
el: "#container",
});
</script>
My question is, how would I create a simple paypal button in Vue 3's script setup? The paypal cdn is imported in the parent blade file.
Something like:
<script setup>
import {onMounted} from "vue";
onMounted(() => {
//create component from -> paypal.Buttons.driver("vue", window.Vue);
})
</script>
<template>
<div id="checkout" class="checkout">
<paypal-buttons></paypal-buttons>
</div>
</template>
I would recommend the following implementation:
Install official paypal-js npm package: npm install #paypal/paypal-js
Then you can write your PaypalButtons Component as follows:
<script setup>
import {Inertia} from '#inertiajs/inertia';
import {loadScript} from '#paypal/paypal-js';
import {onMounted} from 'vue';
const props = defineProps({
// Some kind of reference if you like
reference: Object
});
onMounted(async() => {
try {
const paypal = await loadScript({
'client-id': <your-paypal-client-id>
});
await paypal.Buttons({
createOrder: function() {
function(data, actions) {
return actions.order.create({
purchase_units: [{
amount: {
// e.g reference.price
value: '<your-price>',
},
}],
});
},
onApprove: function(data) {
return actions.order.capture().then(function(orderData) {
// Successful capture!
// e.g. Inertia.post(route('order.update', reference.orderId)
});
},
style: {
// Adapt to your needs
layout: 'vertical',
color: 'gold',
shape: 'rect',
label: 'paypal',
},
// The following is optional and you can
// limit the buttons to those you want to
// provide
fundingSource: paypal.FUNDING.PAYPAL,
}).render('#paypal-button-container');
} catch (error) {
// Add proper error handling
console.error(error);
}
});
</script>
<template>
<div id="paypal-button-container"></div>
</template>
Now use it as:
<PaypalButtons :reference="reference" />
Paypal documentation is a huge mess. The server integration seems to work like so:
if you're using laravel as backend, import this into app.blade.php/welcome.blade.php file:
<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID"></script>
and then your vue component can look like this:
<script setup>
import {onMounted} from "vue";
onMounted(() => {
paypal.Buttons({
// Call your server to set up the transaction
createOrder: function(data, actions) {
return fetch('/demo/checkout/api/paypal/order/create/', {
method: 'post'
}).then(function(res) {
return res.json();
}).then(function(orderData) {
return orderData.id;
});
},
// Call your server to finalize the transaction
onApprove: function(data, actions) {
return fetch('/demo/checkout/api/paypal/order/' + data.orderID + '/capture/', {
method: 'post'
}).then(function(res) {
return res.json();
}).then(function(orderData) {
// Three cases to handle:
// (1) Recoverable INSTRUMENT_DECLINED -> call actions.restart()
// (2) Other non-recoverable errors -> Show a failure message
// (3) Successful transaction -> Show confirmation or thank you
// This example reads a v2/checkout/orders capture response, propagated from the server
// You could use a different API or structure for your 'orderData'
var errorDetail = Array.isArray(orderData.details) && orderData.details[0];
if (errorDetail && errorDetail.issue === 'INSTRUMENT_DECLINED') {
return actions.restart(); // Recoverable state, per:
// https://developer.paypal.com/docs/checkout/integration-features/funding-failure/
}
if (errorDetail) {
var msg = 'Sorry, your transaction could not be processed.';
if (errorDetail.description) msg += '\n\n' + errorDetail.description;
if (orderData.debug_id) msg += ' (' + orderData.debug_id + ')';
return alert(msg); // Show a failure message (try to avoid alerts in production environments)
}
// Successful capture! For demo purposes:
console.log('Capture result', orderData, JSON.stringify(orderData, null, 2));
var transaction = orderData.purchase_units[0].payments.captures[0];
alert('Transaction '+ transaction.status + ': ' + transaction.id + '\n\nSee console for all available details');
// Replace the above to show a success message within this page, e.g.
// const element = document.getElementById('paypal-button-container');
// element.innerHTML = '';
// element.innerHTML = '<h3>Thank you for your payment!</h3>';
// Or go to another URL: actions.redirect('thank_you.html');
});
}
}).render('#paypal-button-container');
})
</script>
<template>
<div id="checkout" class="checkout">
<div id="paypal-button-container"></div>
</div>
</template>
Which payment methods are displayed is determined automatically and depends on your IP (???). You can hide payment methods by manipulating the script import like so:
<script src="https://www.paypal.com/sdk/js?client-id=YOUR_CLIENT_ID&disable-funding=card,giropay,sepa,sofort"></script>

Update Chart vue3-chart with new data

I have Chart.js Chart in a Vue component using vue3-chart-v2.
Everything works fine untill I want to update the data.
Right now, I am using a watcher to check if the data changes.
This works, but updating the chart does not.
My idea was to destroy the chart when the data has changed and rerender it with the new data
I have seen some questions on stack using the mixins reactiveData/ reactiveProp but somehow I can not acces them using vue3-chart-v2, I only get an error.
Could someone help me out?
This my first question here on stack
My code:
<script>
import { defineComponent } from 'vue';
import { Doughnut } from 'vue3-chart-v2';
export default defineComponent({
name: 'PieChart',
extends: Doughnut,
props: {
carbonData: Object
},
data() {
return {
chartData: {
labels: ['Slabs', 'Columns', 'Foundation', 'Core'],
datasets: [
{
data: [ this.carbonData.slabs, this.carbonData.columns, this.carbonData.foundation, this.carbonData.core ],
backgroundColor: ['#8FBC8F', '#87CEFA', '#CD853F', '#e64e3e'],
borderWidth: 1,
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
legend: {
position: 'right',
}
}
}
},
mounted () {
this.renderPieChart();
},
methods: {
renderPieChart() {
this.renderChart(this.chartData, this.options);
}
},
watch: {
carbonData : {
deep: true,
handler() {
this.state.chartObj.destroy();
this.renderChart(this.chartData, this.chartOptions);
},
}
},
})
</script>
We use a simple method:
add a v-if to your chart, for example v-if="renderChart"
It is false in the beginning but when data is loaded change it to true
Whenever you expect the data to change, change it to false again and after change of data update it to true once again.
It has worked for us for a long time now.

Chart.js line graph doesn't show up most of the time

I want to display a chart with money donated and the date of the donation. Mysteriously, the chart shows up sometimes (~5% of the time), yet doesn't the other 95% of the time (See pictures at bottom).
I'm very confused about this issue I'm having. I want to create a line chart using some data I'm getting from an API. I'm using chart.js. Sometimes it shows up and sometimes it doesn't. It has nothing to do with getting the API data as (from looking at the console) that is done immediately. So I am sure it is a problem with my way of using Chart.js.
Here is my LineChart.vue:
<script>
import { Line } from 'vue-chartjs'
export default {
name: 'LineChart',
extends: Line,
props: {
label: {
type: String
},
chartData: {
type: Array
},
options: {
type: Object
}
},
mounted () {
const dates = this.chartData.map(d => d.donationDate).reverse()
const totals = this.chartData.map(d => d.totalMoney).reverse()
this.renderChart({
labels: dates,
datasets: [{
label: this.label,
data: totals
}]
},
this.options)
}
}
</script>
Here is my code for Fundraiser.vue:
<template>
<div class="container">
<div class="row mt-5">
<div class="col">
<h2>Positive</h2>
<line-chart :chart-data=recentDonations :options=chartOptions label='Positive'>
</line-chart>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios'
import moment from 'moment'
import LineChart from '../components/LineChart.vue'
export default {
name: 'Fundraiser',
components: { LineChart },
data () {
return {
recentDonations: [],
chartOptions: {
responsive: true,
maintainAspectRatio: false
}
}
},
async created () {
const { data } = await axios({
url: 'http://api.justgiving.com/[MY API KEY]/v1/crowdfunding/pages/[SOME-PAGE]/pledges',
method: 'get',
headers: {
Accept: 'application/json'
}
})
console.log(data)
data.pledges.forEach(d => { // this part works fine.
if (d.donationAmount != null) {
const dateInEpochFormat = d.activityDate.substring(6, 16)
const donationMade = moment.unix(dateInEpochFormat).format('MM/DD')
this.recentDonations.push({ donationDate: donationMade, totalMoney: d.donationAmount })
}
console.log(this.recentDonations)
})
}
}
</script>
As you can see from the pictue below, the data is being pulled fine (array of objects with two properties: donateDate and totalMoney)
So sometimes it shows up (very very rarely):
[][
Then I refresh the page (without touching ANY code) and all of a sudden:
Can someone please help me solve this mystery?
Try to render the graph after receiving the response from the http request, maybe with an if statement and a variable as flag:
<template>
<div class="container">
<div class="row mt-5">
<div class="col" v-if="show">
<h2>Positive</h2>
<line-chart
:chart-data="recentDonations"
:options="chartOptions"
label="Positive"
>
</line-chart>
</div>
</div>
</div>
</template>
In your export default object, you can have this:
export default {
name: 'Fundraiser',
components: { LineChart },
data () {
return {
show: false,
recentDonations: [],
chartOptions: {
responsive: true,
maintainAspectRatio: false
}
}
},
async created () {
const { data } = await axios({
url: 'http://api.justgiving.com/[MY API KEY]/v1/crowdfunding/pages/[SOME-
PAGE]/pledges',
method: 'get',
headers: {
Accept: 'application/json'
}
})
console.log(data)
data.pledges.forEach(d => { // this part works fine.
if (d.donationAmount != null) {
const dateInEpochFormat = d.activityDate.substring(6, 16)
const donationMade = moment.unix(dateInEpochFormat).format('MM/DD')
this.recentDonations.push({ donationDate: donationMade, totalMoney:
d.donationAmount })
}
console.log(this.recentDonations)
})
this.show = true;
}
}
This is a workaround, You are waiting to have the data before render the graph, than way the first time that the graph is rendered, it can use the data and show the information.
The reason to not see data in the graph is because when the graph is rendered there is not information to show, once you get the response from the http request the graph is not updated, to do so, you must to watch the chartData prop, and once chartData is updated, you must call the chart.js update graph method (you can read more about it here: https://www.chartjs.org/docs/latest/developers/updates.html)
A better way to handle the data update is to assign the value to this.recentDonations after the forEach, that way you are not getting updates every time a pledge is pushed:
...
const donations = [];
data.pledges.forEach(d => { // this part works fine.
if (d.donationAmount != null) {
const dateInEpochFormat = d.activityDate.substring(6, 16)
const donationMade = moment.unix(dateInEpochFormat).format('MM/DD')
donations.push({ donationDate: donationMade, totalMoney:
d.donationAmount })
}
console.log(this.recentDonations)
})
this.recentDonation = donations;
this.show = true;
...
I did a test with a timeout function using this code (I don't know how to use the justgiving api):
<template>
<div class="container">
<div class="row mt-5">
<div class="col" v-if="show">
<h2>Positive</h2>
<line-chart
:chart-data="recentDonations"
:options="chartOptions"
label="Positive"
>
</line-chart>
</div>
</div>
</div>
</template>
<script>
import axios from "axios";
import moment from "moment";
import LineChart from "../components/LineChart.vue";
export default {
name: "Fundraiser",
components: { LineChart },
data() {
return {
show: false,
recentDonations: [],
chartOptions: {
responsive: true,
maintainAspectRatio: false
}
};
},
methods: {
request() {
const pledges = [
{ donationDate: "11/08", donationAmount: 5 },
{ donationDate: "11/09", donationAmount: 5 },
{ donationDate: "11/10", donationAmount: 5 },
{ donationDate: "11/11", donationAmount: 5 },
{ donationDate: "11/12", donationAmount: 5 },
{ donationDate: "11/13", donationAmount: 5 },
{ donationDate: "11/14", donationAmount: 5 },
{ donationDate: "11/15", donationAmount: 5 },
{ donationDate: "11/16", donationAmount: 5 },
{ donationDate: "11/17", donationAmount: 5 },
{ donationDate: "11/18", donationAmount: 5 },
{ donationDate: "11/19", donationAmount: 5 },
{ donationDate: "11/20", donationAmount: 5 },
{ donationDate: "11/21", donationAmount: 5 },
{ donationDate: "11/22", donationAmount: 5 }
];
pledges.forEach(d => {
// this part works fine.
// if (d.donationAmount != null) {
// const dateInEpochFormat = d.activityDate.substring(6, 16);
// const donationMade = moment.unix(dateInEpochFormat).format("MM/DD");
this.recentDonations.push({
donationDate: d.donationDate,
totalMoney: d.donationAmount
});
// }
console.log(this.recentDonations);
});
this.show = true;
}
},
async created() {
await setTimeout(this.request, 1000);
}
};
</script>
If you remove the if statement, the graph doesn't show any data

Using data from API with Chart JS

I am getting data from an api and then reformatting part of it into an array using .map(), I am successfully able to do this, but when it comes time to pass it into Chart JS as data it does work. I am able to pass in a normal, hard coded, array but not my own data...
I tried using an Angular directive (NG2-Charts) to help out thinking maybe that was the problem, but that doesn't work either...
Component.ts:
... Other variable and stuff up here...
getStockData() {
this.stocksService.getStockData()
.subscribe(
(response) => {
for(var i = 0; i < response.length; i++) {
this.stockOpen.push(response[i]['open']);
}
console.log('after loop: ', this.stockOpen);
},
(error) => console.error(error)
);
console.log('real: ', this.stockOpen);
console.log('test: ', this.testData);
}
// Chart JS version
buildStockChart() {
var ctx = document.querySelector("#chart");
this.chart = new Chart(ctx, {
type: 'bar',
data: {
labels: [1,2,3,4,5],
datasets: [
{
data: this.stockOpen,
borderColor: "#3cba9f",
fill: false
}
]
},
options: {
legend: {
display: false
},
scales: {
xAxes: [{
display: true
}],
yAxes: [{
display: true
}],
}
}
});
}
// NG2-Charts version
public lineChartData:Array<any> = [
{data: this.testData},
];
public lineChartLabels:Array<any> = ['January', 'February', 'March', 'April', 'May', 'June', 'July'];
public lineChartOptions:any = {
responsive: true
};
Result from console.log():
i also have same problem with chart JS on angular so i force to use another chart.
im now using angular 2 chart js.
i think the problem here is the delay of data fetch by API, the CHART component is already render on html view but the data is still not fetch by the API service.
try to add this code on your code block. This will handle the data if API service data is available.
()=>{this.buildStockChart();}
this.stocksService.getStockData()
.subscribe(
(response) => {
for(var i = 0; i < response.length; i++) {
this.stockOpen.push(response[i]['open']);
}
console.log('after loop: ', this.stockOpen);
},
()=>{
this.buildStockChart();
}
);
console.log('real: ', this.stockOpen);
console.log('test: ', this.testData);
}
This chart is easy to manage for dynamic instances.
Hope this chart will work on you.
https://www.npmjs.com/package/angular2-chartjs
When are you calling the buildStockChart() method?
You should call it right after the for loop into the callback you pass to the subscribe method, since that's the moment when this.stockOpen is populated (before that moment it will be empty as you are seeing in the console).
As #Joseph Agbing, I was unable to get it work with angular 7. I'm now using chart.js only
npm install chart.js --save
with into my someChart.component.html
<div style="display: block"><!--Mandatory div including chart-->
<canvas id="canvas">{{chart}}</canvas>
</div>
into my someChart.component.ts
called from my httpClient.post(...).subscribe(lData => (setChartDataFromEntities(lDataProcessed), ...)
import { Chart } from 'chart.js';
export class someClass {
/**
*
* #param aDate
* #param aChargeUnitArray
*/
setChartDataFromEntities( aDate: Date, aChargeUnitArray: ChargeUnit[] ){
console.debug('setChartDataFromEntities->', aChargeUnitArray)
let lChartDataArray = []
let lChartDataLineDataArray: Array<Number> = []
let lChartLabelsArray: string[] = []
let l_s: string
aChargeUnitArray.forEach(element => {
lChartDataLineDataArray.push(element.charge)
lChartLabelsArray.push(MiscHelper.dateTimeHMSForChart(element.timestamp))
});
lChartDataArray.push(
{
data: lChartDataLineDataArray,
label: MiscHelper.dateForGui(aDate),
}
)
this.chart = new Chart('canvas', {
type: 'line',
data: {
labels: lChartLabelsArray,
datasets: lChartDataArray
},
options: {
legend: {
display: false
},
scales: {
xAxes: [{
display: true
}],
yAxes: [{
display: true
}],
}
}
});
this.statusMessage = 'Chart loaded'
}
hope it helps somebody more than the day I wasted trying to get it work...

Values not reactive once available in Vuex Store

So I'm retrieving my data from my api using vue-resource which is happening correctly, the state is updated and from the console I am able to see the values I'm requesting. My problem is that when the application loads the data from the store doesn't seem to be impacting the application on load, but if for example I change between pages the information is displayed correctly. This is leading me to believe somewhere along the way I have gotten the life cycle hooks incorrect, or I have handled the state incorrectly inside vuex.
Vuex store
import Vue from 'vue'
import Vuex from 'vuex'
import VueResource from 'vue-resource'
Vue.use(VueResource)
Vue.use(Vuex)
const state = {
twitter: 0,
instagram: 0,
youtube: 0,
twitch: 0
}
const actions = {
LOAD_METRICS: ({commit}) => {
Vue.http.get('http://109.74.195.166:2000/metrics').then(response => {
let out = [{
twitter: Number(response.body[0].twitter),
instagram: Number(response.body[0].instagram),
youtube: Number(response.body[0].youtube),
twitch: Number(response.body[0].twitch)
}]
commit('SET_METRICS', out)
}).catch((e) => {
console.log(e)
})
}
}
const mutations = {
SET_METRICS (state, obj) {
state.twitter = obj[0].twitter
state.instagram = obj[0].instagram
state.youtube = obj[0].youtube
state.twitch = obj[0].twitch
}
}
const getters = {}
export default new Vuex.Store({
state,
getters,
actions,
mutations
})
Here I am trying to dispatch an event to gather the needed information using a mutation.
<template>
<div id="app">
<NavigationTop></NavigationTop>
<router-view></router-view>
<SocialBar></SocialBar>
<CopyrightBar></CopyrightBar>
</div>
</template>
<script>
export default {
name: 'app',
ready: function () {
this.$store.dispatch('LOAD_METRICS')
}
}
</script>
<style>
#import url('https://fonts.googleapis.com/css?family=Roboto:400,700,900');
#app {
font-family: 'Roboto', sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: white;
background: url('./assets/Images/bodyBackground.jpg');
}
</style>
Then finally I am requesting the information inside of the component to be used by countup.js and also giving it to the method inside data.
<template>
<div class="hero">
<div class="container hero-content">
<div class="row hero-back align-items-end">
<div class="col-lg-6">
<div class="row">
<div class="col-lg-6" v-for="icons in socialIcons">
<Hero-Tile
:name="icons.name"
:icon="icons.iconName"
:count="icons.count"
:numeric="icons.numeric"
></Hero-Tile>
<h1>{{origin}}</h1>
</div>
</div>
</div>
</div>
</div>
<div class="diagonal-left-lines"></div>
<div class="home-hero-img"><img class="img-fluid" src="../../assets/Images/home-hero.jpg"></div>
</div>
</template>
<script>
import HeroTile from './Hero-Tile'
import CountUp from 'countup.js'
export default {
components: {HeroTile},
name: 'hero',
data () {
return {
origin: '',
socialIcons: [
{
name: 'twitter',
iconName: 'twitter',
count: this.$store.state.twitter,
numeric: 26000
},
{
name: 'instagram',
iconName: 'instagram',
count: this.$store.state.instagram,
numeric: 35000
},
{
name: 'youtube',
iconName: 'youtube-play',
count: this.$store.state.youtube,
numeric: 15000
},
{
name: 'twitch',
iconName: 'twitch',
count: this.$store.state.twitch,
numeric: 127000
}
]
}
},
methods: {
updateNumbers: function () {
let options = {
useEasing: true,
useGrouping: true,
separator: ',',
decimal: '.',
prefix: '',
suffix: 'K'
}
function kFormatter (num) {
return num > 999 ? (num / 1000).toFixed(1) : num
}
let twitter = new CountUp('twitter', 0, kFormatter(this.$store.state.twitter), 0, 3, options)
let instagram = new CountUp('instagram', 0, kFormatter(this.$store.state.instagram), 0, 3, options)
let youtube = new CountUp('youtube', 0, kFormatter(this.$store.state.youtube), 0, 3, options)
let twitch = new CountUp('twitch', 0, kFormatter(this.$store.state.twitch), 0, 3, options)
twitter.start()
instagram.start()
youtube.start()
twitch.start()
}
},
mounted: function () {
this.updateNumbers()
}
}
</script>
To be clear at the moment it seems to just load '0k' so it's as if there is some form of race condition occurring causing it not to actually load the information on load-up. Though I'm not sure what the correct approach is here.
This was eventually solved by what I'm going to describe as hacking as I don't actually know the exact correct answer at this time. Though what I have does work.
Points of Interest below:
Store
LOAD_METRICS: ({commit}, context) => {
console.log(context)
if (context === true) {
return new Promise((resolve) => {
resolve('loaded')
})
}
return new Promise((resolve) => {
Vue.http.get('real ip is normally here').then(response => {
let out = {
twitter: Number(response.body[0].twitter),
instagram: Number(response.body[0].instagram),
youtube: Number(response.body[0].youtube),
twitch: Number(response.body[0].twitch),
loaded: false
}
commit('SET_METRICS', out)
resolve(out)
}).catch((e) => {
console.log(e)
})
})
}
In the above I am now sending an instance of the current store.state.metrics.loaded when the dispatch event is sent. Which is then checked to see the truthness of the current value, Because the first load should always return false we then return a promise utilizing an API call while also mutating the store so we have the values from later. Thus onwards because we mutated the loaded event to be true the next further instances shall return a value of true and a new promise will be resolved so we can make sure the .then() handler is present.
Component
created: function () {
this.$store.dispatch('LOAD_METRICS', this.$store.state.metrics.loaded).then((res) => {
if (res !== 'loaded') {
this.updateNumbers(res)
} else {
this.socialIcons[0].count = this.kFormatter(this.$store.state.metrics.twitter) + 'K'
this.socialIcons[1].count = this.kFormatter(this.$store.state.metrics.instagram) + 'K'
this.socialIcons[2].count = this.kFormatter(this.$store.state.metrics.youtube) + 'K'
this.socialIcons[3].count = this.kFormatter(this.$store.state.metrics.twitch) + 'K'
}
})
}
Within our component created life cycle hook we then use the resulting values to identify the path to be taken when the components are created within the DOM again, this time just loading the values and allow normal data binding to update the DOM.
I believe there is a better method of approach then deliberating the logic of the state within the action setter and returning a promise that is essentially redundant other than for ensuring the .then() handle is present.

Categories

Resources