0

I am trying to make a GET call from inside a store action. However my Vue.http.get() call throws a TypeError "this is null".

I am at a total loss, and I haven't found anyone else with this specific issue elsewhere. Any help would be appreciated. Thanks

Walkthrough

  1. User navs to /login/
  2. Submits login
  3. Authenticated and token received
  4. Dispatches action to save token and retrieve profile
  5. Error occurs when trying to use Vue.http inside action

Note, the token correctly gets stored in state and localStorage.

Login.vue

methods: {
    submit() {
        this.$http.post(
            this.loginEndpoint,
            this.object
        ).then(response => {
            this.$store.dispatch({
                "type": "auth/save",
                "token": response.body.key,
            }).then(() => {
                this.$router.push({name: "home"})
            }).catch(error => {
                console.log(error)
            })
        }).catch(error => {
            console.log(error)
        })
    }
}

Store

import Vue from 'vue'
import Vuex from 'vuex'
import Auth from '../stores/auth.js'


// plugins
Vue.use(Vuex)


export default new Vuex.Store({
    modules: {
        auth: Auth,
    },
})

auth.js - store module

import Vue from 'vue'


export default {
    namespaced: true,

    state: {
        token: null,
        profile: {},
    },

    mutations: {
        setProfile(state, payload) {
            state.profile = payload.profile
        },

        setToken(state, payload) {
            state.token = payload.token
        },
    },

    actions: {
        save: (context, payload) => {
            return new Promise((resolve, reject) => {
                const url = "/rest-auth/user/"

                context.commit('setToken', {
                    token: payload.token,
                })

                localStorage.setItem("token", payload.token)

                console.log("get user profile")

                // *** Error below calling Vue.http.get ***
                // TypeError: this is null
                Vue.http.get(url).then(response => {
                    console.log("Profile received")

                    context.commit('setProfile', {
                        profile: response.body,
                    })

                    localStorage.setItem("profile", response.body)
                    resolve()

                }).catch(error => {
                    reject(error)
                })
            })
        },
    },
}

Stack Trace

TypeError: this is null
Stack trace:
@webpack-internal:///10:42:9
exec@webpack-internal:///6:1150:21
Client/<@webpack-internal:///6:1179:13
PromiseObj@webpack-internal:///6:200:24
Client@webpack-internal:///6:1143:16
Http@webpack-internal:///6:1400:12
Http[method$$1]@webpack-internal:///6:1431:16
save/<@webpack-internal:///14:112:17
save@webpack-internal:///14:90:20
wrappedActionHandler@webpack-internal:///7:604:15
dispatch@webpack-internal:///7:347:7
boundDispatch@webpack-internal:///7:272:12
submit/<@webpack-internal:///17:100:17
pymarco
  • 7,807
  • 4
  • 29
  • 40
  • What does your setProfile mutation look like? – thanksd Jul 20 '17 at 15:30
  • I have updated the question and added more details to the auth.js code. Thanks – pymarco Jul 20 '17 at 15:35
  • The error only says "this is null"? – thanksd Jul 20 '17 at 15:39
  • Probably unrelated question: Why do you dispatch the action using "type": "auth/save" and not "type": "save"? I've never seen that before.. – andresgottlieb Jul 20 '17 at 16:31
  • @pymarco can you paste the full error text? – andresgottlieb Jul 20 '17 at 16:33
  • Possible duplicate of [How to use vue-resource ($http) and vue-router ($route) in a vuex store?](https://stackoverflow.com/questions/42560318/how-to-use-vue-resource-http-and-vue-router-route-in-a-vuex-store?rq=1). That post may solves your problem. – ironcladgeek Jul 20 '17 at 16:44
  • Possible duplicate of [How to use vue-resource ($http) and vue-router ($route) in a vuex store?](https://stackoverflow.com/questions/42560318/how-to-use-vue-resource-http-and-vue-router-route-in-a-vuex-store) – ironcladgeek Jul 20 '17 at 16:45
  • @andresgottlieb I've added the stack trace to the bottom of the question. Thanks. – pymarco Jul 20 '17 at 17:13
  • @ironcladgeek, I am using `Vue.http` the same as done in the answer to that question. That contributor just abstracts things out a bit more than I am doing here. – pymarco Jul 20 '17 at 17:15
  • 1
    @andresgottlieb regarding dispatch "auth/save". From what I've learned that is how to dispatch to a namedspaced store module's action. The closest documentation that I could find is "Binding helpers with namespace" https://vuex.vuejs.org/en/modules.html – pymarco Jul 20 '17 at 17:17
  • 2
    I'm voting to close this question as off-topic because the issue is specific to my own code and may not contribute generally. – pymarco Jul 20 '17 at 18:09

1 Answers1

0

It turns out that code in my Vue instance was causing the problem. There I was pushing a csrf value to the X-CSRFTOKEN header.

I am using Django and DRF. I just switched from SessionAuthentication to using TokenAuthentication and now have learned that passing the csrf token is not needed.

The code below is from my main.js and after removing it the issue is resolved.

The offending code

/* Add the csrf token to the request header */
Vue.http.interceptors.push(function(request, next) {
    let token = this.$cookie.get("csrftoken")
    request.headers.set('X-CSRFTOKEN', token)
    next()
});

Exactly why this caused the TypeError to be thrown I can't say.

pymarco
  • 7,807
  • 4
  • 29
  • 40