How do I access the Vue object within a Vuex module? - javascript

In Vue components, I can easily use imported libraries, such as vue-router. I can access the route parameter I need with this.$route.params.myVar. However, if I try to do the same within a Vuex module, I get the error: TypeError: Cannot read property 'myVar' of undefined. How can I extend the Vue object I defined in my main.js to my modules?
Here's my main.js:
import router from './router'
import Vuex from 'vuex'
import myModule from './my.module';
Vue.use(Vuex)
// Register VueX modules
const store = new Vuex.Store({
modules: {
myModule
}
})
new Vue({
router,
render: h => h(App),
store
}).$mount('#app')
And my.module.js:
export default {
namespaced: true,
state: {
...
},
mutations: {
...
},
actions: {
someAction() {
console.log(this.$route.params.myVar)
}
}
}
Obviously, this isn't defined. I tried instantiating a new Vue object at the top of my module like so:
var vm = new Vue()
And changing this to vm, but I get a similar Cannot read property 'myVar' of undefined error. I also tried re-instantiating the route class at the the module:
import route from 'vue-router'
And changing my failing code to route.params.myVar, but I still get the Cannot read property 'myVar' of undefined error.

The way I see it, you have two options.
Pass param.myvar from outside inside vuex action
Import router into vuex module and use it
For the second option make sure to import your router declaration and not the library. For example.
import router from '#/router'
router.currentRoute.params.myVar

Related

VueJS 3 CLI project, TypeError default is not a constructor from ModalService

After creating a CLI project, I need to add a Modal dialog, after a bit of searching I found what seems to be a good example at Create Reusable MODALS Using VUE JS, by Shmoji . The tutorial is well written and there is a YouTube as well.
In the modual.service.js file the following code exists:
import Vue from 'vue';
export default new Vue({
methods: {
open(component, props = {}) {
return new Promise((resolve, reject) => {
this.$emit('open', { component, props, resolve, reject });
});
}
}
})
Here is where I get the error that reads:
Uncaught TypeError: vue__WEBPACK_IMPORTED_MODULE_1__.default is not a constructor
It is pointing to the second line of code, export default new Vue({
In my main.js file, I already create Vue so it does not make sense to me why the modal author is trying to overwrite the Vue that already exists?
//main.js
import { createApp, reactive, computed, VueElement } from 'vue'
import App from './App.vue'
import router from './router'
import './assets/styles.css'
import moment from 'moment'
const app = createApp(App).use(router)
app.config.globalProperties.$moment=moment;
app.mount('#app')
Seems to me the global open method needs to be included in main.js but not sure how that is done or how to get around the above error if the modal service open method stays in its own file?
This Modal Dialog is not compatible with Vue3. I answered this question in more detail in this StackOverflow posting.

Is it possible to use route.meta property outside of the component?

I am using Vue 3 in my project and I used route.meta property inside the Vue component but when I moved that into .ts file it doesn't work anymore and in-browser appeared an error.
My .ts file:
import { useRoute } from "vue-router";
import { computed } from "vue";
const route = useRoute();
export const myfunction = computed(() => {
return route.meta.somedata;
});
Error from the browser:
Uncaught (in promise) TypeError: Cannot read property 'meta' of undefined
The same code works fine in .vue files.
Is there any way to use meta property outside of the .vue file?
I found a solution, firstly need to import the router file.
import router from "#/router/index";
Then using the router object we can get currentRoute.value and then access meta properties.
router.currentRoute.value.meta.someData
The final code should look like this:
import { computed } from "vue";
import router from "#/router/index";
export const myfunction = computed(() => {
return router.currentRoute.value.meta.someData;
});

Getting undefined when trying to read vuex state

Following a simple example in VueMaster course and can't seem to read state from the store. Here's my main.js:
import Vue from 'vue'
import upperFirst from 'lodash/upperFirst'
import camelCase from 'lodash/camelCase'
import App from './App.vue'
import router from './router'
import store from './store'
new Vue({
router,
store,
render: h => h(App)
}).$mount('#app')
And here's my index.js in the /store folder:
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
user: { id: 'abc123', name: 'Adam Jahr' },
},
mutations: {},
actions: {},
modules: {}
})
Then, I try and read the state object from a component:
<template>
<div>
<h1>Create an Event, {{ $store.state.user.name }}</h1>
</div>
</template>
I don't see anything in the browser for the component. Console shows an error "TypeError: Cannot read property 'name' of undefined".
Any idea why this very simple example doesn't work? Thanks.
Shouldn't your import look like this:
import store from './store/index'
since that is where you are creating your store, check the folder structure, maybe that is the problem.
I didn't see any problem with your code, it's working as expected.
Here is sandbox link - https://codesandbox.io/s/silly-poitras-sosvs?file=/src/App.vue
You need to provide the store in your component
Something in computed like
return this.$store.state.user

global definition does not work in vue.js

I have tried to import and define a library globally as below, but somehow it does not recognize the global variable.
in main.js,
import Vue from 'vue'
import App from './App'
import router from './router'
import VueJwtDecode from 'vue-jwt-decode'
Vue.config.productionTip = false
Vue.use(VueJwtDecode)
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
components: { App },
template: '<App/>'
})
in Signup.vue,
...
const payload = VueJwtDecode.decode(res.jwt);
...
and the error shows that VueJwtDecode is not defined.
If you are trying to use the named reference of VueJwtDecode, you need to reimport the library in your Signup.vue compoenent since Signup.vue doesn't understand what VueJwtDecode means.
import VueJwtDecode from 'vue-jwt-decode'
const payload = VueJwtDecode.decode(res.jwt);
However, since you have globally installed the library, it has been installed to the Vue instance, meaning that it is available from the this context within your component. As a result, you can also access it from the component context without reimporting:
const payload = this.$jwtDec(res.jwt);
As document, in your component, you need to use
this.$jwtDec(res.jwt)
instead of
VueJwtDecode.decode(res.jwt);

Vuex store modules not loading in right order when importing store directly

I'm probably not seeing obvious, but after hours I don't get it still.
The problem: when I import my Vuex store into a non-component file (a api service), one module gets loaded properly while the other one only by name, but is otherwise empty.
// store.js
import * as collections from "./modules/collections";
import * as auth from "./modules/auth";
export default new Vuex.Store({
modules: {
auth,
collections
}
});
Both these modules are near-identical. Both have
export const getters = {}
export const actions = {}
export const mutations = {}
export const state = {}
Now when in some other non-component file I DON'T include the store, my vue store looks like this:
{"auth":{"authenticated":false,"authToken":"123","loginPending":false,"loginError":{}},"collections":{"collectionsPending":false,"collectionsError":null,"collections":[]}}
Now when I import the store to use it in my service like so:
import store from '../store'
// NO OTHER MENTIONS OF STORE, ONLY IMPORTING
Suddenly only my auth module is "empty"
{"auth":{},"collections":{"collectionsPending":false,"collectionsError":null,"collections":[]}}
It has something to do with module loading.
Order of loading by adding console.log statements:
Without the import:
INIT AUTH
INIT collections
INIT store
With the import:
INIT collections
INIT store
IMPORT STATEMENT -- INTO SERVICE
INIT AUTH
I'm using the Vue Webpack Boilerplate
Sigh, sorry. Circular dependency indeed. Was expecting a warning if I'd did that, but didn't.
Thanks Emile Bergeron.

Categories