Getting router params into Vuex actions
Asked Answered
M

4

23

I would like to pass router params into Vuex actions, without having to fetch them for every single action in a large form like so:

edit_sport_type({ rootState, state, commit }, event) {
  const sportName = rootState.route.params.sportName <-------
  const payload = {sportName, event}                 <-------
  commit(types.EDIT_SPORT_TYPE, payload)
},

Or like so,

edit_sport_type({ state, commit, getters }, event) {
  const payload = {sportName, getters.getSportName}  <-------
  commit(types.EDIT_SPORT_TYPE, payload)
},

Or even worse: grabbing params from component props and passing them to dispatch, for every dispatch.

Is there a way to abstract this for a large set of actions?

Or perhaps an alternative approach within mutations themselves?

Marikomaril answered 11/2, 2017 at 17:21 Comment(0)
F
35

To get params from vuex store action, import your vue-router's instance, then access params of the router instance from your vuex store via the router.currentRoute object.

Sample implementation below:

router at src/router/index.js:

import Vue from 'vue'
import VueRouter from 'vue-router'
import routes from './routes'

Vue.use(VueRouter)

const router = new VueRouter({
  mode: 'history',
  routes
})

export default router

import the router at vuex store:

import router from '@/router'

then access params at vuex action function, in this case "id", like below:

router.currentRoute.params.id
Flesher answered 9/12, 2017 at 8:1 Comment(6)
For me doesn't full worked. I had to import router from '../router/index.js' inside actions.jsAfterlife
@Heichou, indeed, in the above answer, there is a statement to import router, under this phrase 'import the router at vuex store:'Flesher
Yes you're right but I'm saying I imported it inside actions.js instead of store.js!Afterlife
@Heichou, Oh I see. You're right. We import a package where it is used. As long as I can remember, what I mean vuex store in the above answer is a whole system that manage state in VueJs app. By the way, i didnt fiddled with vuejs for about 2 years now, so maybe there's invalid info from me this time. ThanksFlesher
I did exactly as described here, but when I debug my action, the router is undefined. If there some scoping issue I need to resolve so I can use router within my actions functions?Duodenary
Note: In vue 3 it will be router.currentRoute.value.params.id note the value part.Lemke
M
2

Not sure to understand well your question, but :
This plugin keeps your router' state and your store in sync :
https://github.com/vuejs/vuex-router-sync

and it sounds like what you are looking for.

Menthol answered 13/2, 2017 at 23:16 Comment(2)
I think @Menthol is right here. See the How does it work? section of the vuex-router-sync README. Adding vuex-router-sync add a route module to the store so you can now access things like path, params, and query.Guenna
As you can see by my use of rootState.route.params, I'm already using vue-router-syncMarikomaril
C
1

You can use this function to get params into Vuex

import router from './router';
router.onReady(()=>{
   console.log(router.currentRoute.params.sportName)
})
Choker answered 18/1, 2023 at 13:40 Comment(0)
R
0

To my knowledge ( and I've looked into this for a project I'm working on ) no, there is not. The simplest way to do this is to abstract route fetching or anything you want to do to a service and use it in your vuex file or if you use modular approach import it in you actions.js file.

so paramFetching.js file would look like this:

export default {
  fetchRouteParams: function() {
    // do fetching
    // you should return a promise 
  }
}

Then import that into your vuex

import service from 'paramFetching.js'

And then make an action like so

...
fetchParamsAction: function({commit}) {
  service.fetchRouteParams()
    .then( (response) => { // stuff gottten from service. you should o your commit here } )
    .catch( (error) => { // error handling } )
}

And then just dispatch this action and everything will be handled in an action. So it kinda isolates that from the rest of the code. This is just a general idea. I'm sorry if it's not clear enough. If I can help further, please ask.

Razorbill answered 12/2, 2017 at 14:23 Comment(4)
Thanks for the answer. That sounds like a lot more work than just using a getter (as shown above)Marikomaril
I didn't use this in the same situation as you. You can choose what suits you best, but this solution is more flexible and it separates concerns. In the end the choice is yours. GLRazorbill
More flexible in js in general perhaps, but since you can use a getter pretty much anywhere in vue, not sure.Marikomaril
Yeah :) I like to use getters only for accessing the state... and I hardly ever use them in vuex actions... so it might be that my approach is wrongRazorbill

© 2022 - 2024 — McMap. All rights reserved.