New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug Report][3.1.14] Components built with @/composables/router can crash when routes are missing required params #17176
Comments
May be related to vuejs/router#845 |
This issue doesn't seem to be caused by the code related to vuejs/router@4108814 as commenting out the current version of the dev tools code and running the application does not resolve this issue. Instead it seems that the buttons are getting re-rendered when the route changes causing it to re-resolve the route link which becomes impossible because at the time of re-rendering the routable buttons, the router has already changed its state to not have the relevant params. |
So after quite a bit of investigation this is what I've learned. Components in Vuetify that make use of the
Vuetify's What I am seeing is that every time the current route changes, Vuetify's router enabled components get an update, causing it to re-resolve the route for every link. And when the new route is missing params required for the links' named route, the resolution of the href property fails causing the crash. You would expect components to unmount gracefully when you leave a route that loads and renders router link components using named routes which require params, what happens is that this route re-resolve operation takes place BEFORE the components get unmounted. This is basically a race condition. I have come up with a workaround, but it should be considered a hack and not a solution. This hack works for In the parent component, you need to obtain the current router params and store them in a const. const routeParams = { ...useRoute().params };
Then in your template you will want to do something like this. <VBtn :to="{ name: 'RouteName', params: routeParams }">Your Router Link Button</VBtn> This way you'll be passing in the necessary params to make your link properly resolve even if your route changes to something that doesn't contain the necessary params. |
Awesome work @MatthewAry ! I can confirm your workaround. I also pass params to v-tab (in my case). |
I asked @posva about this and he said:
|
Confirming this issue on my side as well 🙏🏻 |
I have created hack that should satisfy most use-cases but I have not done comprehensive testing of it. My hope is that it will make sure the required params are fed to the routable components. Also, please note that this solution has room for optimization. If you moved the routes map out of the https://gist.github.com/MatthewAry/7129cfe405f93bb5827e7cbd7928dd40 Update: |
Maybe I don't understand the actual issue or I don't know how to use vue-router "correctly", but isn't the problem, that the |
It should be implicitly inherited.
…On Fri, Apr 28, 2023, 1:29 AM 1Luc1 ***@***.***> wrote:
Maybe I don't understand the actual issue or I don't know how to use
vue-router "correctly", but isn't the problem, that the params: { pid:
'...' } for v-btn :to within the views/example/Example.vue file aren't
defined? Like it is in components/HelloWorld.vue.
—
Reply to this email directly, view it on GitHub
<#17176 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AABGMIJJ3AOJ7VJ6RP57WA3XDN5VRANCNFSM6AAAAAAXCZ66A4>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
Playing around a bit, i got the same problem with I set up an quick example about the problem here: https://github.com/1Luc1/list-props-to-bug Basically there are two Layouts. One Layout holds a child component. Switching from one layout to the other causes the following browser warning during development (npm run dev): [Vue warn]: Unhandled error during execution of watcher callback
at <VListItem title="Right View #1" value=undefined prependIcon="$arrowRight" ... >
at <VListChildren items= Array [ {…}, {…} ] >
at <VList items= Array [ {…}, {…} ] density="compact" active-color="primary" >
at <VCol cols="auto" >
at <VRow class="d-flex justify-center" >
at <VResponsive class="d-flex text-center fill-height" >
at <VContainer class="fill-height" >
at <BaseLayout onVnodeUnmounted=fn<onVnodeUnmounted> ref=Ref< Proxy { <target>: Proxy, <handler>: {…} } > >
at <RouterView>
at <App> runtime-core.esm-bundler.js:40:16 I noticed, that for the list items, the missing Building and running the app, leads to the following error: Error: Missing required param "id"
...
Update: After 4 months without any reasonable solution for this problem I'm using MatthewAry's workaround for now, which works quite well for me. I updated my issue repo with his workaround and hope this issues will get resolved in the future. |
@MatthewAry Could you please explain how your hack/fix applies to the bug i reported earlier ( #17614 ), As described in this bug , we are unable to navigate to the However i don't understand why we would need params to navigate to Also once you try navigating to |
I was able to do this and your patch resolves the issue in my codebase also. Thanks. |
Linking this here since it seems relevant. |
@johnleider can we expect this to be fixed in blackguard? |
We don't have someone specifically on it atm. Would you be interested in taking the reigns on this? |
I might have the confidence to take this on in the future, but right now I don't because this bug is weird and the actual cause of the problem is unknown. It would be better to figure out the cause then to just make a workaround. With that said, I think a workaround solution is possible. We can probably use RegEx, Matched Routes, and Resolve methods in the router to solve this; but extensive tests would need to be written to ensure that all functionality detailed https://router.vuejs.org/guide/essentials/route-matching-syntax.html is maintained. This code might help but I'm not that great with RegEx so there might be bugs: function resolvePath(path, params) {
// Handle optional params
path = path.replace(/\?/g, "\\?")
// Handle repeating params
path = path.replace(/\*/g, "(\\/[^/]+)*")
path = path.replace(/\+/g, "(\\/[^/]+)+")
// Handle custom regex
path = path.replace(/:\w+\([^\)]*\)/g, "([^/]+)")
// Extract all dynamic params
const paramMatches = path.match(/:[^/()]+/g)
if (!paramMatches) return path
// Replace each param with its value
let resolvedPath = path
for (const param of paramMatches) {
const name = param.slice(1)
if (name in params) {
resolvedPath = resolvedPath.replace(param, params[name])
}
}
return resolvedPath
} Using the router's resolve method could return a path for a named route but without any of the params applied. The function above can then take the params provided in an object and try to apply them to the path by matching against the path's keys. This solution however leaves the actual router out of a part of the route resolution process. Honestly it would be better if the router would allow us to provide an excessive amount of params and let it handle it instead of doing something like this. |
Hello, we had the same issue and we resolved it by upgrading some dependencies (with
|
Sadly, for us this did not work out. We were already on the mentioned versions and still experience the bug. Hoping for a timely resolution of this issue. |
We're looking for help on this issue. |
Environment
Vuetify Version: 3.1.14
Vue Version: 3.2.47
Browsers: Chrome 112.0.0.0
OS: Mac OS 10.15.7
Steps to reproduce
This is a really dirty reproduction. Clone, and
npm i
and run.There are two buttons, click on "VBtn Flaw" and then click on the home button in the top right corner.
Expected Behavior
Click on "Router Link" and then click on the home button on the top right corner. And see the expected behavior.
I expect that when you use a named route which is a child to a parent(s) with param(s) that it will inherit the params implicitly from it's parent, you shouldn't need to declare the params that are missing.
Actual Behavior
VBtn in the example crashes when you navigate back to home.
Reproduction Link
https://github.com/MatthewAry/vuetify-route-link-bug
Other comments
This reproduction shows the behavior with
RouterLink
and withVBtn
theto
params on the elements shown on those pages are basically the same. I think behaviorally when it comes to routing, there should be no difference betweenRouterLink
andVBtn
or any other component that uses @/composables/routerUpdate: vuejs/router#845 has to do with this exact problem however the issue was closed because the team believed it was resolved. If you build your application in production mode you won't see this issue. See: vuejs/router#845 (comment) Which suggests that
this issue may be upstreamor that theuseLink
method in@/composables/router
needs to changein some manner to be more similar to what the RouterLink component is doingto avoid this issue. 🤷Update: See #17176 (comment)
The text was updated successfully, but these errors were encountered: