Vue data fetched object not available in setup() - vue.js

I am rendering a jspreadsheet component with data fetched from fastapi.
<template>
<h1>Synthèse évaluation fournisseur</h1>
<VueJSpreadsheet v-model="data.table" :options="myOption" />
{{ data.columns }}
</template>
<script>
import { reactive, onMounted, isProxy, toRaw, ref } from "vue";
import VueJSpreadsheet from "vue3_jspreadsheet";
import "vue3_jspreadsheet/dist/vue3_jspreadsheet.css";
export default {
components: {
VueJSpreadsheet,
},
setup() {
// var intervalID = setInterval(init, 3000);
var data = reactive({
table: [],
columns: [],
});
async function load_data() {
const response = await fetch("http://LOCALHOST:8080/supplier_overview");
return await response.json();
}
load_data().then((response)=>{
data.table=JSON.parse(response.result.data)
data.columns=(response.result.columns)
});
console.log(data.columns)
const myOption = ref({
columns: data.columns,
search: true,
filters: true,
includeHeadersOnDownload: true,
includeHeadersOnCopy: true,
defaultColAlign: "left",
tableOverflow: true,
tableHeight: "800px",
parseFormulas: true,
copyCompatibility: true,
});
return {
data,
myOption,
};
},
};
</script>
whereas data.columns is rendered correctly in the template, I cannot pass it to myOptions .
The proxy is empty with console.log(data.columns) whereas {{data.columns}} returns the correct array :
[ { "title": "period" }, { "title": "fournisseur" }, { "title": "Qualité" }, { "title": "Rques Qualité" }, { "title": "Logistique" }, { "title": "Rques Logistique" }, { "title": "Cout" }, { "title": "Rques Cout" }, { "title": "Système" }, { "title": "Rques Système" }, { "title": "Mot QLCS" }, { "title": "Note" }, { "title": "Rques" } ]
Any ideas why I cannot passed it correctly to myOptions ?

This problem has nothing to do with the variable myOptions
setup() {
async function load_data() {
const response = await fetch("http://LOCALHOST:8080/supplier_overview");
return await response.json();
}
//the function is async, 1 will be called after 2, so the result is empty
load_data().then((response)=>{
data.table=JSON.parse(response.result.data)
//1
data.columns=(response.result.columns)
});
//2
console.log(data.columns)
}

Related

how can insert scema object in mongoose expresss

this my model app
import mongoose, { mongo, Schema } from "mongoose";
const app = mongoose.Schema({
'name':{
type: String
},
'parent':{
type: String
},
'order':{
type:Number
},
'path':{
type: String,
},
'accesses': [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Accesses"
}
]
},
{ timestamps: true },);
export default mongoose.model('Apps',app);
this my model accesses
import mongoose, { mongo } from "mongoose";
const accesses = mongoose.Schema({
'name':{
type: String,
require: true
},
'app':[{
type: mongoose.Schema.Types.ObjectId,
ref: "Apps"
}]
},
{ timestamps: true },);
export default mongoose.model('Accesses',accesses);
this my controller
export const saveApp = async (req,res) => {
try {
const app = new App(req.body);
const accesses = app.accesses;
let newAccs = [];
for (const acc of accesses)
{
const newAcc = await Accesses.findById(acc._id)
newAccs.push(newAcc);
}
app.accesses = newAccs;
const result = await app.save()
res.status(201).json(result);
} catch (error) {
res.status(400).json({message: error.message});
}
}
this my client.rest
POST http://localhost:3000/app
Content-Type: application/json
{
"name": "Ads Management testing",
"parent": "null",
"order": 1,
"path": "ads-management/",
"accesses": "63689567eee823ff6f39e969"
}
this my result
{
"name": "Ads Management testing",
"parent": "null",
"order": 1,
"path": "ads-management/",
"accesses": [
{
"app": [],
"_id": "63689567eee823ff6f39e969",
"name": "rejected",
"createdAt": "2022-11-07T05:19:35.590Z",
"updatedAt": "2022-11-07T05:19:35.590Z",
"__v": 0
}
],
"_id": "636a09d82ea451f510a56534",
"createdAt": "2022-11-08T07:48:40.035Z",
"updatedAt": "2022-11-08T07:48:40.035Z",
"__v": 0
}
my expecting data nested like this
why in my mongose accesses just put an id not all of object

v-if is not updated when importing a 3rd party script with vue-meta

I want to use vue-meta to import a 3rd party SwiperJS script into my nuxt website.
The script is loaded only after mounted()-hook is called so I also initialize it on update(). This kind of works but the v-if on the wrapper does not update.
<template>
<section
class="swiper"
v-if="isSwiperLoaded"
>
<div class="swiper-wrapper"> ... </div>
</section>
</template>
<script>
export default {
data() {
return { swiperLoaded: false, swiperInitialized: false }
},
computed: {
isSwiperLoaded: {
get() {
return this.swiperLoaded
},
set(value) {
this.swiperLoaded = value
},
},
isSwiperInitialized: {
get() {
return this.swiperInitialized
},
set(value) {
this.swiperInitialized = value
},
},
},
head() {
return {
script: [
{
hid: 'swiper',
src: 'https://cdn.jsdelivr.net/npm/swiper#8/swiper-bundle.min.js',
defer: true,
// Changed after script load
callback: () => {
this.isSwiperLoaded = true
},
},
],
link: [
{
rel: 'stylesheet',
type: 'text/css',
href: 'https://cdn.jsdelivr.net/npm/swiper#8/swiper-bundle.min.css',
},
],
}
},
methods: {
initSwiper() {
const swiperOptions = {
...
}
let swiper = new Swiper(this.$el, swiperOptions)
},
},
mounted() {
if (!this.isSwiperInitialized && this.isSwiperLoaded) {
console.log('INIT LOADED')
this.initSwiper()
this.isSwiperInitialized = true
}
},
updated() {
if (!this.isSwiperInitialized && this.isSwiperLoaded) {
console.log('UPD LOADED')
this.initSwiper()
this.isSwiperInitialized = true
}
},
}
</script>
Also I noticed the computed values are normally for getting and setting values from store and not local values. Maybe there is an easier way of updating the variables.

Vue.js access variable from method

I try to fetch stocks data from an API. This data should be used to create a chart.js graph.
how do I access in vue.js data to generate a chart.js line chart from the methods http(axios) call?
Is it possible to access the data directly in the mounted component or should I define a const in the section and create the variables there?
<template>
<select v-model="selected">
<option v-for="option in options" :value="option.value">
{{ option.text }}
</option>
</select>
<div>Selected: {{ selected }}</div>
<div>
<canvas id="myChart" height="200" width="650"></canvas>
</div>
<script>
export default {
mounted() {
const ctx = document.getElementById("myChart");
const myChart = new Chart(ctx, {
type: "line",
data: {
labels: [prices[0].date],
datasets: [
{
label: 'Dataset msft',
data: prices[0].price
},
{
label: 'Dataset google',
data: prices[1].price
},
],
},
});
},
data() {
return {
selected: "",
prices: [],
options: [
{ text: "msft", value: "msft" },
{ text: "GOOGL", value: "GOOGL" },
],
};
},
watch: {
selected: function () {
this.getPrice();
},
},
methods: {
getPrice: function () {
var this_ = this;
axios
.get(
"https://site/...."
)
.then((response) => {
// JSON responses are automatically parsed.
this_.prices = response.data;
})
},
},
};
</script>
Yes, you can access variables in data() from mounted().
You need to prepend variables with this. when using the Options API
ex: this.prices[0].price
As you are putting watcher on selected but I did not see any changes in the selected variable in your code. As per my understanding you are making an API call to get the graph data based on the selected option.
If Yes, Instead of generating a chart in mounted you can generate it inside your getPrice() method itself based on the response. It should be :
methods: {
getPrice: function () {
var this_ = this;
axios
.get(
"https://site/...."
)
.then((response) => {
this.generateChart(response.data);
})
},
generateChart(prices) {
const ctx = document.getElementById("myChart");
const myChart = new Chart(ctx, {
type: "line",
data: {
labels: [prices[0].date],
datasets: [
{
label: 'Dataset msft',
data: prices[0].price
},
{
label: 'Dataset google',
data: prices[1].price
}
]
}
});
}
}
Here, a very basic example:
<script>
export default {
async mounted() {
await this.$nextTick();
const ctx = document.getElementById("myChart");
this.chart = new Chart(ctx, {
type: "line",
data: {
labels: [],
datasets: [],
},
});
},
data() {
return {
selected: "",
chart: null,
options: [
{ text: "msft", value: "msft" },
{ text: "GOOGL", value: "GOOGL" },
],
};
},
watch: {
selected: function () {
this.getPrice();
},
},
methods: {
async getPrice() {
let { data } = await axios.get("https://site/....");
this.chart.data.datasets = [{ label: "dummy data" , data: [2, 3, 4]}];
this.chart.data.label = [1, 2, 3];
this.chart.update(); //very important, always update it
},
},
};
</script>
You create a property called chart and save your chart to it.
Then, after you fetch your data, you can access your chart with this.chart and then you set your datasets and labels. Whenever you make an change to the chart, use this.chart.update() to update it on the browser.
If you execute this code, you should see some dummy data in the chart

Initialization of variables with Vuex

I made a VueJS 3 project with VueX to store the data.
When I print the variable data.doughnutChart.data in the following code it displays
{ "labels": [ "OK", "WARNING", "ERROR" ], "datasets": [ {
"backgroundColor": [ "#d4efdf", "#fdebd0", "#fadbd8" ], "data": [ 3,
1, 2 ] } ] }
But the graph doesn't use these data [3,1,2], the graph uses the values of the initialization in the index.js of VueX.
Here my code :
<template>
{{data.doughnutChart.data}}
<div style="height:200px;width: 200px; position:center">
<vue3-chart-js
:id="data.doughnutChart.id"
:type="data.doughnutChart.type"
:data="data.doughnutChart.data"
:options="data.doughnutChart.options"
></vue3-chart-js>
</div>
</template>
<script>
import Vue3ChartJs from '#j-t-mcc/vue3-chartjs'
export default {
name: 'App',
components: {
Vue3ChartJs,
},
beforeMount() {
this.$store.dispatch("getData");
},
computed: {
data() {
return {
doughnutChart: {
id: 'doughnut',
type: 'doughnut',
data: {
labels: ['OK', 'WARNING', 'ERROR'],
datasets: [
{
backgroundColor: [
'#d4efdf',
'#fdebd0',
'#fadbd8'
],
data: [this.$store.state.nbOk, this.$store.state.nbWarning, this.$store.state.nbError]
}
]
},
options:
{
plugins: {
legend: {
display: false
},
title: {
display: true,
text: 'Current situation'
}
},
}
}
}
}
}
}
</script>
I read the value in my index.js (VueX) :
import axios from 'axios'
import { createStore } from 'vuex'
export default createStore({
state: {
data: [],
nbError : 0,
nbWarning : 0,
},
actions: {
getData({commit}){
axios.get('http://localhost:8080/data/mock.json')
.then(res => {
commit('SET_DATA', res.data)
})}
},
mutations: {
SET_DATA(state, data){
state.data = data.data;
state.nbWarning = 0;
state.nbError = 0;
for (let i = 0; i < state.data.length; i++) {
if(state.data[i].status == 'WARNING'){
state.nbWarning += 1;
};
if(state.data[i].status == 'ERROR'){
state.nbError += 1;
};
};
}
})
However it works when, in my Vuejs project, I go in an other page and come back but not when I just open the project or refresh the page.
Do you know why ?
data property should be defined as computed in order to receive store changes:
<template>
{{data}}
</template>
<script>
export default {
data() {
return {
}
},
computed:{
data(){
return [this.$store.state.nbWarning, this.$store.state.nbError]
}
},
beforeMount() {
this.$store.dispatch("getData");
}
}
</script>

Can't render chart, data from api

I get data from api. i can show chartdata but it not render a chart.
my code:
<script>
import { Pie, mixins } from 'vue-chartjs'
import axios from 'axios'
export default {
mixins: [mixins.reactiveData],
extends: Pie,
data() {
return {
chartdata: ''
}
},
mounted () {
this.renderChart(this.chartdata, this.options)
},
created() {
axios.get("http://localhost:3000/chart1")
.then(response => {
const responseData = response.data
this.chartdata = {
labels: responseData.map(item => item.lb),
datasets:
[
{
label: 'hrlo',
backgroundColor: ['purple','#b2b2b2'],
data: responseData.map(item => item.dt)
}
]
}
})
.catch( e => {
this.errors.push(e)
})
},
}
</script>
api: [
{
"lb": "Android",
"dt": 80
},
{
"lb": "IOS",
"dt": 20
}
]
i'm sorry because of my bad english.
Can you also include any error messages? I am suspecting that the wrong data structure of "chartdata" is causing an error before even retrieving the data to display, i.e. "chartdata" needs to be
chartdata: {
labels: [],
datasets: []
}