Changing Vue Data Object - javascript

UPDATED CODE
<template>
<swiper-slide v-for="(photon,key) in $store.state.photons" :key='key'>
<radial-gauge :value='photon.tempF'
:options="photon.GaugeOptions.optionsLastTempF"></radial-gauge>
</swiper-slide>
</template>
store.js
export const store = new Vuex.Store({
state: {
photons: {},
token: '',
},
mutations: {
setUser(state, value) {
value.data.forEach(element => {
state.photons[element.id].user = element.data
state.photons[element.id].GaugeOptions.optionsLastTempF.highlights[0].to=parseInt(element.data.tempAlert,10)
state.photons[element.id].GaugeOptions.optionsLastTempF.highlights[1].from=parseInt(element.data.tempAlert,10)+1
});
}},
actions: {
async getData(context) {
let db = []
let photon = {}
db = await axios.get('http://13.14.13.1:3300/DB')
db.data.forEach(item => {
if ([Object.keys(item)[0]] in photon) {
let dataString = (Object.values(item)[0]).split(',')
photon[Object.keys(item)[0]].GaugeOptions={}
photon[Object.keys(item)[0]].GaugeOptions.optionsLastTempF={
title: 'Last Temp',
units: "°F",
minorTicks: 10,
majorTicks: ['0', '20', '40', '60', '80', '100', '120', '140', '160'],
maxValue: 160,
highlights: [{
"from": 0,
"to": 0,
"color": "rgba(0,255,0)"
},
{
"from":0,
"to": 160,
"color": "rgba(255,0,0)"
},
],
colorPlate: '#222',
colorUnits: '#ccc',
colorTitle: '#eee',
colorNumbers: '#eee',
width: 200,
height: 200
}
context.commit('setData', photon)
}
}
}
This code currently works if I go from the homepage to my chart page where this gauges are, but if i refresh the page the gauges have the right values but they aren't being properly update.
UPDATE
so after adding a v-if to my component it now loads properly with everything. I'm now having trouble with how I would call an update function on the gauge?If i'm doing the mutation in my vuex store how would i reference my component to call an update?

So, typically, Vuejs does not watch nested objects. I'd recommend that you rework you code a bit to avoid this. This should help: Vue.js - How to properly watch for nested data
Additionally, it looks like you are trying to reference the Vuex Store object, but you are using the data method rather than the computed method, so you won't get updates on that.

Related

Fetch live-updating data from an IDB (Dexie) using Vue.js

I am trying to display a live logs table using Vue(quasar)+Dexie.
I managed to display the data using the basic example from the dexie doc page:
export default {
name: "Logs",
setup() {
const columns = [
{
name: "ts",
label: "TimeStamp",
field: "ts",
align: "left",
format: (val, row) => date.formatDate(val, "HH:mm:ss:SSS"),
},
{
name: "action",
label: "Action",
field: "action",
align: "left",
format: (val, row) => val,
},
{
name: "status",
label: "Status",
field: "status",
align: "left",
format: (val, row) => val,
},
{
name: "data",
label: "Data",
field: "data",
align: "left",
format: (val, row) => {
return val;
},
},
];
const pagination = ref({
sortBy: "ts",
descending: true,
page: 1,
rowsPerPage: 10,
});
return {
columns,
pagination,
dialog: [],
logs: useObservable(
liveQuery(() => useDatabase.logs.reverse().limit(10).toArray())
),
};
},
};
I get a new Log entry every 1 second.
I am almost sure that the whole bulk of data is re-fetched and not appended. Am I right?
Is there a better practice for loading live updating data from a table than this? (if it's really as i described)
Instead of re-loading all the data from IDB, to just fetch the newly added entries and append them.
I have the same exact situation when displaying a live updating chart (using ApexCharts).
but in this case, I fetch 256 samples per second. I want the components to render the data "automatically" using Vues superpowers while pointing to a ref.
Usually when working with frontend frameworks, and specifically Vue, I create some kind of a variable let logs = ref({...}) and whenever there new data, it gets rendered only when and where it's needed. It doesn't re-render the whole bulk all over again.
I hope my problem is clear, and if not, the examples or my way of thought is understood. I might be thinking this wrong, but i'd be happy to learn from others experience.

How to get data from API through vue chartjs?

this is my first time posting here, i'm working on an application where i need to get data from an API and show it through a chart (i'm using vue chart js). The code is almost done, i can see in the console the API's data.
Showing API's data in console
This is my chart/api conection:
<template>
<div>
<bar-chart
:data="barChartData"
:options="barChartOptions"
:height="150"
:width="150"
/>
</div>
</template>
<script>
import BarChart from "~/components/BarChart";
const chartColors = {
grey: "rgba(210, 210, 210, 0.2)",
white: "rgb(255,255,255)",
};
export default {
components: {
BarChart,
},
data() {
return {
barChartData: {
asistencia: [],
labels: [],
datasets: [
{
label: "Income",
backgroundColor: [chartColors.white, chartColors.grey],
data: [0,0],
},
],
},
barChartOptions: {
responsive: true,
legend: {
display: true,
},
},
};
},
async fetch() {
this.asistencia = await fetch(
'http://127.0.0.1:8000/apiasistenciausuarioAsistenciaUsuario/',
).then(res => res.json())
console.log(this.asistencia);
},
components: {
BarChart,
},
methods: {
refresh() {
this.datos();
this.$nuxt.refresh();
},
datos() {
this.barChartData.datasets[0].data = [
this.res.is_presente,
];
},
}
};
As you can see i send the data to the console but the "Asistencia" graphic is not showing and that's because it isn't getting the data sucessfully
datos() {
this.barChartData.datasets[0].data = [
this.res.is_presente,
];
barChartData should get the data from "is_presente" var from the API but that var is a boolean so i was thinking on doing a validation to check when it's true/false and make a counter to fill the graphic.
datos() {
this.barChartData.datasets[0].data = [
if(this.res.is_presente == true){
count++;
}else{
count--;
}
];
I don't know how to do this, i have the idea but i don't know how to execute this....
Thanks in advance!

How to set react state values from another state values?

I have an array of objects in state:
const [formFields, setFormFields] = useState([
{
height: 45,
label: "tv",
placeholder: "555",
name: "tv",
maxWidth: 203,
value: dataValues.tv,
priority: 1
},
{
height: 45,
label: "radio",
placeholder: "50%",
name: "radio",
maxWidth: 126,
value: dataValues.radio,
priority: 2
},
{
height: 45,
label: "instagram",
placeholder: "60%",
name: "instagram",
maxWidth: 126,
value: dataValues.instagram,
priority: 3
}
]);
I need each state value to be updated when another state updates (when I click on submit money button each state value should update), but it is not updating.
you can check the demo
any help please?
Your input elements have their value set based upon your formFields object. When you initially make the object, you use values from your dataValues object, and dataValues will automatically update based on your apiData object due to what you wrote in your useEffect hook, however you never actually wrote anything to update formFields itself.
The following code should make it work as is,
const newFormFields = [...formFields];
newFormFields[0].value = apiData.tv;
newFormFields[1].value = apiData.radio;
newFormFields[2].value = apiData.instagram;
setFormFields(newFormFields);
However I'd strongly advise refactoring. It seems like you've got a whole lot of needless redundancy here.
You mentioned in a comment that can't use indexes. In that case, something like this should work.
const newFormFields = [...formFields];
newFormFields.map(field => (field.value = apiData[field.name]));
setFormFields(newFormFields);

Add several nested JSON properties in a component in React

I am learning React and have a API request to OpenWeather that results in something like this:
{
coord: {
lon: -0.13,
lat: 51.51
},
weather: [{
id: 500,
main: "Rain",
description: "light rain",
icon: "10d"
}],
base: "stations",
main: {
temp: 293.21,
pressure: 1011,
humidity: 86,
temp_min: 292.45,
temp_max: 294.26
},
wind: {
speed: 1.54,
deg: 243,
gust: 3.08
},
rain: {
3h: 0.78
},
clouds: {
all: 56
},
dt: 1466431324,
sys: {
type: 3,
id: 10115,
message: 0.0463,
country: "GB",
sunrise: 1466394185,
sunset: 1466454093
},
id: 2643743,
name: "London",
cod: 200
}
I'm having problems using several parts of this JSON data.
I can call the result and first layer without problems, but calling any of the nested properties responds in an error saying it can't read the property of undefined.
I guess this is because the state is not defined, does it need to be defined for all the nested layers? I have defined the root, like this:
var React = require('react');
var Httprequest = require('../services/weatherservice.js');
var CurrentWeather = require('./CurrentWeather.jsx');
var WeatherApp = React.createClass({
getInitialState: function() {
return {currentWeather: '', apiCall: ''};
},
componentWillMount: function() {
Httprequest.get('London')
.then(function(data) {
this.setState({apiCall: data});
this.setState({currentWeather: data.weather[0]});
}.bind(this));
},
render: function() {
var Res = this.state.apiCall;
return (
<div>
<h1>Weather App</h1>
<CurrentWeather weatherNow={Res.main.humidity} />
</div>
);
}
});
module.exports = Weather;
Perhaps I shouldn't use state? I'm thinking of creating a solution where the user can change the city later on that's why I'm using state. I would appreciate it a lot if someone experienced could explain and perhaps refactor my example using a good practice so that I can learn doing it right.
Let me try to explain what you have done)
1) before first render you send request which will return data, at state you have {currentWeather: '', apiCall: ''}
2) request is async, so
.then(function(data) {
this.setState({apiCall: data});
this.setState({currentWeather: data.weather[0]});
}.bind(this))
this code will be called after several seconds
3) render method called, in which you doing something like this:
this.state.apiCall.main.humidity
but, for now in state you still have {currentWeather: '', apiCall: ''} so we will have error
how to solve this? simple just add some checks like
weatherNow={Res && Res.main && Res.main.humidity}
i also recommend you to read react styleguids, for now your component look ugly)

Backbone.js: Update Collection with different data

I have a Backbone Collection of Models that have different data coming in on page load than when it's fetched.
For example, the attributes coming in on page load are:
[{ name: 'cat', color: 'yellow' },
{ name: 'dog', color: 'brown' },
{ name: 'fish', color: 'orange' }]
Then, on fetch() (or otherwise updated from the server while the page lives, the data looks like:
[{ name: 'cat', current: 5, total: 100 },
{ name: 'dog', current: 6, total: 50 },
{ name: 'fish', current:7, total: 25 }]
How can I update the Backbone Collection with the new data while retaining the old data? IDs are not assigned from the server (name is guaranteed unique).
I ended up going with this. This will update the properties for models that exist while also removing models that did not come in and adding new ones.
Backbone.Collection.prototype.update = function(col_in){
var self = this,
new_models = [];
_(col_in).each(function(mod_in) {
var new_model = self._prepareModel(mod_in),
mod = self.get(new_model.id);
if (mod) {
new_models.push(mod.set(mod_in, {silent:true}));
} else {
new_models.push(mod_in);
}
});
this.reset(new_models);
};
Note the use of _prepareModel this is important so that the Models can be identified via whatever "id" property is used in the Backbone Model object.

Categories