0
votes

I've got what's basically the default Vue JS scaffolding that comes with Laravel.

// app.js
require('./bootstrap');

window.Vue = require('vue');

const app = new Vue({
    el: '#app',
    methods: {
        refreshToken: function() {
            console.log('refreshing the token');
        }
    }
});

// bootstrap.js
window._ = require('lodash');
window.Popper = require('popper.js').default;

try {
    window.$ = window.jQuery = require('jquery');

    require('bootstrap');
} catch (e) {}

window.axios = require('axios');

window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

let token = document.head.querySelector('meta[name="csrf-token"]');

if (token) {
    window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}

This should be familiar to anyone who has used Vue JS with Laravel before.

Now i've tried to add an axios interceptor to handle errors, i've done this below the X-Requested-With header in bootstrap.js

window.axios.interceptors.response.use(
    response => response,
    error => {
        // Show the user a 500 error
        if (status >= 500) {
            console.log({500:error});
        }

        // Handle Session Timeouts
        if (status === 401) {
            console.log({401:error});
            app.refreshToken();
        }

        // Handle Forbidden
        if (status === 403) {
            console.log({403:error});
        }

        return Promise.reject(error)
    }
);

The console.log() instances work fine to verify that it is working.

However app.refreshToken() does not work (and does not give an error either?).

I'm not that surprised since I haven't imported it or anything.

But i've tried this at the top of bootstrap.js: import app from './app.js';

And npm run watch now throws a warning:

"export 'default' (imported as 'app') was not found in './app.js'

I modified app.js to change const app to be export const app but this didn't make any difference.

I'm pretty sure I am just missing some basic understanding of importing and exporting within es6 but unfortunately I can't find anything on Google that will explain it.

Most of my Googling of how to setup this axios interceptor to handle errors has come up with examples using vuex. I really don't want to bring in vuex just to resolve this as I don't want to touch it until i'm sure it's necessary for my particular app and it definitely seems overkill just to be able to follow a tutorial.

How can I call my app.refreshToken() method or access my vue instance within the axios interceptor?

1
have you tried adding it on app.js instead of boostrap? ... you'd be making some kind of require import loop otherwise, i think ... Since app calls bootstrap, and then you make bootstrap call app ..Erubiel
export/import is only used when you have split this up into modules(separate files). It seems like you have everything within boostrap.js so this is totally not of any concern here, so you shouldn't be using it. First thing I would do is to simply log out the app const to see if it actually holds your Vue instance and to rule out any scope issues.Stephan-v
Everything isn't in bootstrap.js, it's in app.js which calls bootstrap.js at the very start. And @Erubiel it seems better to not have a bloated app.js file surely? If my interceptor grows app.js could get very, very large.John Mellor

1 Answers

0
votes

After

require('./bootstrap');

window.Vue = require('vue');

const app = new Vue({
    el: '#app',
    methods: {
        refreshToken: function() {
            console.log('refreshing the token');
        }
    }
});

Add what the error says it's missing:

"export 'default' (imported as 'app') was not found in './app.js'

Just add this:

export default app;

That might solve the compilation problem, as for the call to the function, i have not tested it yet... came with a very similar problem 15 minutes ago..