0

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?

1 Answer 1

1

You can use $emit in your signIn method :

signIn: function () {
  axios.put(`${process.env.API_URL}/login`, {email: this.email, password: this.password})
    .then(resp => { // Success
      //...
      // what I want to do...
      this.$emit('loaded')
    }
  }  
}

and catch this emit in the parent :

<session-modal @loaded="loading = true"></session-modal>

Simple fiddle example here

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.