25

Is there a way to pass additional data to $router.push() that is not registered as param or query in the route's path. This will allow me to recognize on the next page that it has been accessed via programmatic navigation as there is no way to pass it via URL. Something like:

this.$router.push({
   path: '/next-page', 
   params: {...}, 
   query: {...}, 
   moreData: {foo: 1}
})

And then in /next-page:

this.$route.moreData.foo // 1

Currently I am using the $store to handle moreData

4
  • Can you try meta instead of moreData? Commented Oct 4, 2018 at 6:46
  • 2
    I tried .push({meta: {foo: 1}}) but after the transition $route.meta is empty object ( {}) Commented Oct 4, 2018 at 6:48
  • And why cant you make it via a query? Commented Oct 4, 2018 at 7:02
  • 2
    Cuz the parameter is private Commented Oct 4, 2018 at 7:17

2 Answers 2

56

I found the solution. There is a Note in the Vue-router docs that says:

Note: params are ignored if a path is provided ... Instead, you need to provide the name

So we are allowed to pass custom data to params if we navigate using route's name like so:

$router.push({name: 'next-page', params: {foo: 1}})

// in /next-page
$route.params.foo // 1
Sign up to request clarification or add additional context in comments.

5 Comments

@slim, And what is the url for this route name? Is data passed through URL?
@AkshayDeshmukh No, its not passed through the url but is accessible via $route.params. The url is that one that corresponds to the route with that name. There should be only one route with that name as it is considered a unique identifier. Of course if I navigate to a route { name: 'users-id', params: {id: 1}} that has a path = '/users/:id' the id will be present in the url as well.
Phew, what a frustrating bug of theirs that params only work with named route, this took me forever to figure out, thanks!
@Kevin its not really a bug. They simply use single source of truth. If you pass path they must extract the params from there. Otherwise they look for a params object :) Though, they should probably always try to merge both with a higher priority on path in case of name collision.
Also please be aware that if you have multiple languages you need to use localePath function or any function language aware as the route names are generated with a suffix.
2

In my case I was using the name redirect, but couldn't receive the custom params because the target route had a redirect by path - in this case the provided params were lost.

So it was required to change from the 'path redirect' to the 'named redirect', but since 'path redirect' contained an additional data in the path, I now need to pass that data via the 'name redirect' as well using params.

So I ended up with a helper "redirectByName" function that preserves the params in this case:

redirectByName.js

//redirects by preserving params
export default (name, params = {}) => {
    return (route) => ({
        ...route,
        name,
        params: {
            ...route.params,
            ...params
        }
    })
}

And here is an example how to use it:

myRoutes.js

    import redirectByName from "./redirectByName";
    ...
    export default return [
        {
            path:'some/path',
            name: 'targetRouteName',
            redirect:redirectByName('redirectRouteName', {tab: 'general'}), //optional additional parameters for redirection
        }, 
        {
            path:'some/path/:tab', 
            name: 'redirectRouteName'
        }]

The redirectByName basically takes the target route object to preserve all the passed data, overrides its name parameter with the provided one and merges the params. Then it passes the final route object back to accomplish the redirect.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.