0๐
So the problem was a lack of understanding about how actions work in Vuex. What was happening is that the async call would not cause the repaint of the orders. To do something that is asynchronous you need to use actions in Vuex. These allows for something like calling an api and waiting for that resolution before committing that information to the state through the mutations which are the reactive portion of vuex. This also meant that I had to change a lot of my local data into computed data and return the contents of the storage instead of using getters to populate my local storage.
This also allowed me to then update the station nav component to use the vuex storage properly.
Bellow I am posting the changed files that now work as expected.
/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
greenboard :{
station: 1,
incomplete_orders:[],
complete_orders:[],
},
yellowboard:{
incomplete_orders:[],
complete_orders:[],
},
dashboard:{
},
},
getters: {
greenIncomplete: state => {
return state.greenboard.incomplete_orders;
},
greenComplete: state => {
return state.greenboard.complete_orders;
},
greenStation: state => {
return state.greenboard.station;
}
},
mutations: {
updateGreenOrders (state,payload){
console.log(payload);
state.greenboard.incomplete_orders = payload.incomplete_orders;
state.greenboard.complete_orders = payload.complete_orders;
state.greenboard.station = payload.station;
},
updateGreenStation (state,payload){
Vue.delete(state.greenboard, 'station');
Vue.set(state.greenboard, 'station', payload.station);
}
},
actions: {
async updateGreenOrders(context,payload){
try{
const incomplete = await axios.get('/internal/green-orders/'+payload.station+'/0/');
const complete = await axios.get('/internal/green-orders/'+payload.station+'/1/');
context.commit({
type:"updateGreenOrders",
incomplete_orders: incomplete.data.data,
complete_orders:complete.data.data,
station:payload.station
});
}catch(e){
console.log(e);
}
}
}
});
StationsNav.vue
<template>
<ul>
<li v-for="station in stations" v-bind:key="station.id" v-on:click="stationChange(station.id)">{{station.station_name}}<br />{{station.description}}</li>
</ul>
</template>
<script>
export default {
name:'StationsNav',
components:{},
data(){
return {
stations: [],
chosen_station:0 ,
error:"",
}
},
created(){
this.fetchStations();
},
methods:{
async fetchStations(){
try{
const res = await axios.get('/internal/stations/');
this.stations = res.data.data;
}catch(e){
console.log(e);
}
},
stationChange(stationId){
this.$store.dispatch({
type:"updateGreenOrders",
station:stationId
});
}
},
mounted() {
}
}
</script>
GreenOrders.vue
<template>
<div class="container-fluid">
<!--button class="buton" v-on:click="debug">
debug
</button-->
<div class="row justify-content-center">
<div class="col-md">
<h3>Green Orders Station {{station}}</h3>
<p>
These orders are referenced from the Woocomerce system for orders that are ready to be shipped.
</p>
<order-card
v-on:orderstatuschange = "changeOrderStatus"
v-for="order in orders_incomplete"
v-bind:key="order.id"
v-bind:id="order.id"
v-bind:order_id = "order.order_id"
v-bind:number_of_items = "order.number_of_items"
v-bind:completion = "order.completion"
></order-card>
</div>
<div class="col-md">
<h4>Monitor Completed Orders</h4>
<p>
Completed orders eventually fall out of the system once their status is updated in Woocomerce
</p>
<order-card
v-on:orderstatuschange = "changeOrderStatus"
v-for="order in orders_complete"
v-bind:key="order.id"
v-bind:id="order.id"
v-bind:order_id = "order.order_id"
v-bind:number_of_items = "order.number_of_items"
v-bind:completion = "order.completion"
></order-card>
</div>
</div>
</div>
</template>
<script>
export default {
name:'OrdersDisplay',
components:{},
data(){
return {
error:"",
}
},
computed: {
orders_incomplete(){
return this.$store.state.greenboard.incomplete_orders;
},
orders_complete(){
return this.$store.state.greenboard.complete_orders;
},
station(){
return this.$store.state.greenboard.station;
}
},
created(){
this.fetchOrders(this.station);
},
methods:{
fetchOrders(station){
this.$store.dispatch({
type:"updateGreenOrders",
station:this.station
});
},
async changeOrderStatus(order){
try{
const res = await axios.post('/internal/order/'+order.id+'/'+order.status+'/');
this.fetchOrders(this.station);
}catch(e){
console.log(e);
}
},
intervalUpdate(){
var s = this;
setInterval(function () {
s.fetchOrders(s.station);
}, 1000);
},
debug(){
console.log("I'M THE CREAM OF THE CROP!")
}
},
mounted() {
//this.intervalUpdate();
//this.fetchIncomplete(this.station);
//this.fetchComplete(this.station);
//console.log(this.$store.state.greenboard.incomplete_orders);
}
}
</script>
GreenBoard.vue
<template>
<div class="container-fluid">
<div class="row">
<div class="col-3">
<!--stations-nav v-on:stationChange="updateGreenStation"></stations-nav-->
<stations-nav></stations-nav>
</div>
<div class="col-9">
<green-orders></green-orders>
</div>
</div>
</div>
</template>
<script>
export default {
name:'GreenBoard',
components:{},
data(){
return {
}
},
created(){
},
methods:{
},
mounted() {
}
}
</script>
Documentation that illuminated the problem: https://vuex.vuejs.org/guide/actions.html#dispatching-actions-in-components
Conclusion
To simplify the problem so that it is hopefully helpful to others in the future.
If you are using Vuex you need to use mutations to be reactive. If something is asynchronous you need to use an action and the cycle looks like this.
dispatch action -> action resolves -> commit results -> vue reacts.
If any of the other more experienced people on the site have additional input please let me know. Thank you Decade Moon for the comment that sent me down this path.