I'm hoping I am missing something simple here because it seems like there should be a trivial solution to this. I am trying to hide the spinner on the parent component by changing the v-model on the parent component from the child component.
I've tried accessing the parent via this.$parent.data and this.$refs. The $parent and $refs seem to exist in the console, but I cannot access the data I am looking for.
I've also tried sending a message to the 'parent' component by using this.$dispatch('message-name', 'message') which resulted in the following error
_this2.$dispatch is not a function
Here is my child component
SessionModal.vue
<template>
<v-layout row justify-center>
<v-dialog v-model="modalOpen" persistent max-width="290">
<v-card>
<v-card-title class="headline">Session Expired</v-card-title>
<v-card-text>Please login to continue</v-card-text>
<v-card-text>
<v-form>
<v-text-field prepend-icon="person" name="login" label="Email" type="text" v-model="email" ></v-text-field>
<v-text-field prepend-icon="lock" name="password" label="Password" id="password" type="password" v-model="password"></v-text-field>
</v-form>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn color="green darken-1" flat @click.native="signIn">SIGN IN</v-btn>
<v-btn color="green darken-1" flat @click.native="sendToLogin">SIGN OUT</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</v-layout>
</template>
<script>
import axios from "axios";
import * as decode from "jwt-decode";
export default {
data () {
return {
modalOpen: null,
email: null,
password: null
}
},
mounted () {
this.checkAuthStatus()
setInterval(function () {
this.checkAuthStatus();
}.bind(this), 15000);
},
methods: {
setHeaders: function () {
let token = localStorage.token;
return { headers: {'token': token} }
},
checkAuthStatus: function () {
axios.get(`${process.env.API_URL}/auth_status`, this.setHeaders())
.then((resp) => {
console.log('resp', resp);
this.modalOpen = false;
})
.catch((err) => {
console.log('auth failed', err.message);
this.modalOpen = true;
})
},
sendToLogin: function () {
this.modalOpen = false;
delete localStorage.token
this.$router.push('/sign_in')
},
closeModal: function () {
this.modalOpen = false;
},
signIn: function () {
axios.put(`${process.env.API_URL}/login`, {email: this.email, password: this.password})
.then(resp => { // Success
this.badPassword = false;
this.modalOpen = false;
// set local storage
localStorage.token = resp.data.token;
// what I want to do...
this.$parent.data.loading = false;
}, error => { // Failed
console.log('there is an error', error);
this.badPassword = true
});
}
}
}
</script>
And here is the parent component
Payment.vue
<template>
<v-app>
<spin-baby-spin v-if="loading"></spin-baby-spin>
<v-content>
<session-modal></session-modal>
<v-container fluid v-if="loading == false">
<v-layout row>
<v-flex>
<v-card>
<-- rest of template -->
<script>
import Spinner from './Spinner';
import SessionModal from './SessionModal';
import axios from 'axios';
import numeral from 'numeral';
import * as decode from 'jwt-decode';
import {Decimal} from 'decimal.js';
export default {
data () {
return {
insuffienctFunds: false,
user: null,
fee: 0,
disableSubmit: false,
success: false,
valid: false,
loading: true,
currencyRates: null,
e6: 1,
beneficiaries: [],
payment: {
amount: '',
originCurrency: 0,
beneficiaryCurrency: 1,
beneficiary: {
text: '',
id: null
}
},
e1: null
},
components: {
'spin-baby-spin': Spinner,
'session-modal': SessionModal
},
methods: {
submit: function () {
this.disableSubmit = true;
if (this.getTotal() > this.balance) {
this.insuffienctFunds = true;
this.disableSubmit = false
return
}
const transferPayload = this.formatTransferData();
axios.post(`${process.env.API_URL}/transfers`, transferPayload, this.setHeaders())
.then((resp) => {
console.log(resp)
this.success = true;
})
.catch((err) => {
console.log(err)
})
},
decodeToken () {
return decode(localStorage.token);
},
setHeaders: function () {
let token = localStorage.token;
return { headers: {'token': token } }
},
getUser: function () {
let userId = this.decodeToken().userId;
return axios.get(`${process.env.API_URL}/users/${userId}`, this.setHeaders())
},
getUserBalance: function () {
let userId = this.decodeToken().userId;
return axios.get(`${process.env.API_URL}/users/${userId}/balance`, this.setHeaders())
},
},
mounted () {
this.loading = false;
},
created() {
this.loading = false;
this.getUser()
.then(user => {
this.user = user.data
})
this.getUserBalance()
.then(userBalance => { this.balance = userBalance.data.balance })
}
}
</script>
I have removed code which I do not think contribute to the issue in order to make this a faster read.
The behavior I am seeing is once the modal pops up over the page, and the user signs in through the modal. The modal then disappears, but the spinner component does not hide. Even though the component seems to go through the vue component lifecycle and mounts as expected aside from the loading model
Any thoughts on how to access the Payment.vue data from the SessionModal.vue component?