I am working on Django and Vue js using GraphQL and Vuex store to communicate between my frontend and my backend.
When I send a request from my frontend, I get a 200 OK response from my backend but on my frontend, I get an error titled
TypeError: Cannot read property 'token' of undefined.
Here is an overview of my code starting from
// The apolloClient Trigger
import { apolloClient } from '../../apollo'
import {USER_ID, AUTH_TOKEN } from '../../constants/settings'
// The User Authentication mutation and queries
import {SIGNIN_USER_MUTATION} from "../../graph/auth/mutation"
const state = {
token:null,
userId:"",
errorMsg:"",
authStatus: false,
}
const getters = {
isAuthenticated: state => !!state.userId,
authStatus: state => state.authStatus
}
const mutations = {
SET_TOKEN(state, token){
state.token = token,
state.authStatus = true
},
SET_USER_ID(state, userId){
state.userId = userId
},
ERR_TOKEN(state, err){
state.errorMsg = err
}
}
const actions = {
// The user login API
async userLogin({commit}, authDetails){
try{
const response = await apolloClient.mutate({
mutation: SIGNIN_USER_MUTATION,
variables: { ...authDetails }
});
const token = JSON.stringify(response.tokenAuth.token)
const userId = JSON.stringify(response.tokenAuth.user.id)
console.log(token)
commit('SET_TOKEN', token)
commit ('SET_USER_ID', userId)
localStorage.setItem(AUTH_TOKEN, token)
localStorage.setItem(USER_ID, userId)
}
catch(e){
console.log(e)
}
},
}
export default {
state,
getters,
mutations,
actions,
}
<template>
<div class="min-h-screen flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
<div class="max-w-md w-full space-y-8 rounded-lg bg-white px-8 py-8 shadow-md">
<div>
<img class="mx-auto h-12 w-auto" src="/img/area.svg" alt="Workflow">
<h2 class="font-body mt-6 text-center text-xl tracking-wider text-gray-900">
Sign in to your account
</h2>
</div>
<form class="mt-8 space-y-6">
<input type="hidden" name="remember" value="true">
<div class="rounded-md shadow-sm space-y-8">
<div>
<label for="email-address" class="font-body text-gray-900 tracking-wider">Email address</label>
<input v-model = "authDetails.email" id="email-address" name="email" type="email" autocomplete="email" required class="mt-3 appearance-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-md focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm" placeholder="Email address">
</div>
<div>
<label for="password" class="font-body tracking-wider text-gray-900">Password</label>
<input v-model = "authDetails.password" id="password" name="password" type="password" autocomplete="current-password" required class="mt-3 appearance-none relative block w-full px-3 py-2 border border-gray-300 placeholder-gray-500 text-gray-900 rounded-lg focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 focus:z-10 sm:text-sm" placeholder="Password" >
</div>
</div>
<div class="flex items-center justify-between">
<div class="flex items-center">
<input id="remember_me" name="remember_me" type="checkbox" class="h-4 w-4 text-indigo-600 focus:ring-indigo-500 border-gray-300 rounded">
<label for="remember_me" class="ml-2 block text-sm text-gray-900 font-body tracking-wider">
Remember me
</label>
</div>
<div class="text-sm">
<a href="#" class="font-body font-medium text-gray-600 tracking-wider hover:text-green-600">
Forgot your password?
</a>
</div>
</div>
<div>
<button v-on:click.prevent="loginUser()" type="submit" class="group relative w-full flex justify-center py-2 px-4 border border-transparent text-sm rounded-md text-white font-body tracking-widest bg-red-600 hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500" >
<span class="absolute left-0 inset-y-0 flex items-center pl-3">
<!-- Heroicon name: lock-closed -->
<svg class="h-5 w-5 text-white group-hover:text-white" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
<path fill-rule="evenodd" d="M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z" clip-rule="evenodd" />
</svg>
</span>
Sign in
</button>
</div>
</form>
</div>
</div>
</template>
<script>
import { mapActions } from 'vuex'
export default {
data(){
return{
authDetails:{
email:"",
password:"",
}
}
},
methods:{
...mapActions(['userLogin']),
loginUser:function(){
this.userLogin(this.authDetails).then(() => this.$router.push('/feeds')
)
}
}
}
</script>
3auth.js?c7d4:76 TypeError: Cannot read property 'token' of undefined
at _callee$ (auth.js?c7d4:62)
at tryCatch (runtime.js?96cf:63)
at Generator.invoke [as _invoke] (runtime.js?96cf:293)
at Generator.eval [as next] (runtime.js?96cf:118)
at asyncGeneratorStep (asyncToGenerator.js?1da1:3)
at _next (asyncToGenerator.js?1da1:25)
Alright, thanks to everyone who has contributed to this, and finally I get my answers.
I made a mistake when referencing the data from the backend, it was supposed to be this way
const token = JSON.stringify(response.data.tokenAuth.token)
const userId = JSON.stringify(response.data.tokenAuth.user.id)