Vue.js Vuex action do not see getter from other module - vue.js

Im trying to use getter from other module to get JWT token to my http query, which is looking like that:
...
},
actions: {
async refreshContactData( state, getters, rootState, rootGetters ) {
return axios.get('/test', {
headers: {
Authorization: 'Bearer ' + rootGetters['user/getJWT']//the token is a variable which holds the token
}
}).then(response => {
console.log(response)
})
}
},
}
my second modlue look like this:
//user.js
import axios from "axios"
export default {
state: {
jwt: 'asdfasdf',
},
getters: {
getJWT: (state) => {
console.log("WTF")
return state.jwt;
}
},
...
its connected with main index.js store file:
//index.js
...
modules: {
user: User,
contact: Contact
},
...
i tried different configuration but im still getting "undefined" error in console:
vue.runtime.esm.js?2b0e:1888 TypeError: Cannot read property 'user/getJWT' of undefined
at _callee$ (contact.js?7526:54)
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)
at eval (asyncToGenerator.js?1da1:32)
at new Promise (<anonymous>)
at eval (asyncToGenerator.js?1da1:21)
at Store.refreshContactData (contact.js?7526:47)
What am i doing wrong?

Actions don't have multiple arguments like getters do. They have a context argument and a payload argument. To get the rootGetters you can destructure the context argument:
async refreshContactData({ rootGetters }) { // notice the braces
...
}
Then rootGetters will be defined.

Related

Uncaught (in promise) TypeError: Cannot create property 'token' on string

Am trying to implement authentication using vuex. I have a register component and also a auth.js for submiting data.
My backend API are working fine but the issue is when i try to login. When i console log in action method am able to get the token.
when i console log before the SET_TOKEN mutation am also able to get data.
But in mutations the data is received like an object. How do I solve the error?
import axios from "axios"
export default{
namespaced: true,
state: {
token: null,
user: null
},
mutations: {
SET_TOKEN(access_token, state){
console.log(this, access_token)
state.token = this,access_token
},
},
actions: {
async loginUser({ dispatch }, form) {
let response = await axios.post('/api/auth/login', form)
dispatch('attempt', response.data.data.access_token)
},
async attempt({ commit }, access_token){
commit('SET_TOKEN', access_token)
}
}
}
I think you mixed up the order of mutation parameters a little bit. First is state, second is payload (token in your case)
SET_TOKEN(state, token) {
state.token = token;
},

Call a service api with Nuxt.js

I am using nuxt.js and I´d like to create a folder to put all my services api.
So, I create a services folder called services and I put into it my first service api:
// ClientesService.js in services folder
export default ($axios) => ({
list() {
return $axios.get('clientes')
},
})
Now, in my component, I call the service, but I get an error
TypeError: _services_ClientesService__WEBPACK_IMPORTED_MODULE_12__.default.list is not a function
at _callee2$ (medicos.vue?9853:155:1)
at tryCatch (runtime.js?96cf:63:1)
at Generator.invoke [as _invoke] (runtime.js?96cf:294:1)
at Generator.eval [as next] (runtime.js?96cf:119:1)
at asyncGeneratorStep (asyncToGenerator.js?1da1:3:1)
at _next (asyncToGenerator.js?1da1:25:1)
at eval (asyncToGenerator.js?1da1:32:1)
at new Promise (<anonymous>)
at eval (asyncToGenerator.js?1da1:21:1)
at VueComponent.getEspecialidades (medicos.vue?9853:155:1)
// My component
....
<script>
import ClientesService from '#/services/ClientesService'
export default {
name: 'Medicos',
data: () => ({
loading:false,
especialidades:[]
}),
async mounted() {
await this.getEspecialidades()
},
methods: {
async getEspecialidades() {
this.loading = true
try {
const resp = await ClientesService.list()
this.especialidades = resp.data
} catch (error) {
console.log(error)
} finally {
this.loading = false
}
},
},
}
</script>
I'd recommend create an ApiService that is just an axios instance (where you can define base api url, default headers, interceptors, etc) and use it in all other services. The code should look something like
import axios from 'axios';
const ApiService = new axios.create({
timeout: 30000,
baseURL: 'YOUR_API_URL',
headers: {
buildApplicationVersion: '1.0',
},
});
export default ApiService;
import ApiService from '#/Services/ApiService';
const list = () => {
return ApiService.get('clientes')
}
const CustomerService = {
list
}
export default CustomerService;

Using mapActions correctly with nuxt.js

I need to use mapActions in a nuxt.js store.
If I call the "dispatch" method all is ok, but when I use the mapActions I get 'Maximum call stack size exceeded' error.
// storequiz.js
export const state = () => ({
quizVersion: null,
stage: null,
title: null,
img: null,
questions: [],
currentQuestion: null,
answers: [],
})
export const mutations = {
setQuizVersion(state, version) {
state.quizVersion = version
},
setQuestions(state, questions) {
state.questions = questions
},
}
export const actions = {
async fetchData({ commit }, payload) {
const res = await this.$axios.get(payload)
commit('setQuizVersion', res.data.version)
commit('setQuestions', res.data.questions)
},
}
// my methods:
methods: {
...mapActions({
fetchData: 'storequiz/fetchData',
}),
async fetchData() {
// await this.$store.dispatch('storequiz/fetchData', this.url)
await this.fetchData(this.url)
},
....
I am getting the error:
error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE
client.js?06a0:103 RangeError: Maximum call stack size exceeded
at new Context (runtime.js?96cf:449)
at Object.wrap (runtime.js?96cf:41)
at _callee2 (Quiz.vue?b7d7:182)
at eval (asyncToGenerator.js?1da1:22)
at new Promise (<anonymous>)
at eval (asyncToGenerator.js?1da1:21)
at VueComponent.fetchData (Quiz.vue?b7d7:182)
at _callee2$ (Quiz.vue?b7d7:182)
at tryCatch (runtime.js?96cf:63)
at Generator.invoke [as _invoke] (runtime.js?96cf:293)
If I use: await this.$store.dispatch('storequiz/fetchData', this.url)
instead of await this.fetchData(this.url), all works well.
What am I missing here?
The mapped fetchData is hidden by the subsequent method of the same name. You should rename one of them for unique method names (if they're both needed).
Also, the component method fetchData calls itself unconditionally, so there's an infinite loop that would lead to the Maximum call stack size exceeded. Add a condition to break out of the loop (if this call is even needed).

Jest Vuex: Error in created hook: "TypeError: Cannot read property 'dispatch' of undefined"

I am currently trying to mock out the two Vuex actions that is called in the created() Vue hook, however, Jest keeps returning "TypeError: Cannot read property 'dispatch' of undefined", this is what I have tried:
Test file:
let store
let actions
beforeEach(() => {
actions = {
setApiUrl: jest.fn(),
init: jest.fn()
}
store = new Vuex.Store({
modules: {
membership: membershipTestData
},
actions
})
})
const wrapper = shallowMount(
Component,
store,
localVue
)
await wrapper.vm.setApiUrl('')
await wrapper.vm.init()
expect(actions.setApiUrl).toHaveBeenCalled()
expect(actions.init).toHaveBeenCalled()
Component file:
created () {
this.setApiUrl('')
this.init()
},
methods: {
...mapActions('membership', ['init', 'setApiUrl'])
}
Please can anyone suggest what I am doing wrong here, I have tried everything I could, but the test still fails due to the created() hook error.
I have solved it, where I went wrong was the in the wrapper, which should be (notice the diff in curly brace)
const wrapper = shallowMount(Component, {
localVue,
propsData
})

Vue/ Nuxt - run code after the entire view has been rendered?

I want to create a few functions after after the entire view has been rendered / mounted:
export default {
mounted: function () {
this.example = function() {
return 'example'
},
function() {
console.log('mounted') // does not work
}
},
created () {
console.log(this.example()) // error
},
methods: {
submitMessage() {
console.log(this.example()) // example
}
}
}
Why do I get the error below at created()?
TypeError: this.example is not a function
at VueComponent.created (index.vue:119)
at callHook (vue.runtime.esm.js:2661)
at VueComponent.Vue._init (vue.runtime.esm.js:4222)
at VueComponent (vue.runtime.esm.js:4392)
at createComponentInstanceForVnode (vue.runtime.esm.js:3674)
at init (vue.runtime.esm.js:3491)
at createComponent (vue.runtime.esm.js:5143)
at createElm (vue.runtime.esm.js:5086)
at VueComponent.patch [as __patch__] (vue.runtime.esm.js:5602)
at VueComponent.Vue._update (vue.runtime.esm.js:2420)
Any ideas?
The created hook is called before the mounted hook. When the created() function runs, this.example has not yet been declared.
You will be able to call this.created() after it has been declared.
Refer to the lifecycle diagram.