-
-
Notifications
You must be signed in to change notification settings - Fork 107
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
Can a guard function send props to a component? #147
Comments
You can pass props using userData |
Thanks @BogdanDarius, I was reading that, but couldn't find the relation between user data and props |
Well you can use static props if you want to send a specific id to the component. export let id and inside the routes wrap({
props: { id: 1000 }
}) |
Sounds like what you're looking for is a sort of "middleware" and this is not really possible at the moment in the router. And I do think your best option remains to re-do the normalization in the route. How complicated (computationally intensive) is the function that normalizes the ID? |
I guess not that much, and also it's not running on my CPUs :) |
I didn't want to say it out loud, but indeed 😁 If you really wanted to avoid re-computing it, I would look into Svelte stores as a possible tool to keep this state. Because only one page can be displayed at a time, it shouldn't be an issue. Aside from that, I sense an ask here for the ability to pass data from a route guard to a component. In a broader sense, that would be turning route guards into "middlewares". You're the first one to ask for something like this, so I'll keep this open to see if there's others who have a similar need. The good news is that there are workarounds at least: besides re-computing, using "global state" such as Svelte stores should allow this. |
This allows route pre-condition functions to pass params to components The proposed API is not final See #147
I've been thinking about this and I have a proposed design for you to consider! I do not consider this final at all, but more like a "request for feedback" 😄 The idea is to introduce the "context". Your route pre-condition functions now receive as Each key in the context is then passed to the component's For example: routes.js (fragment) export default {
'/hello/:first/:last?': wrap({
component: Name,
conditions: [
function (detail) {
this.setContext('foo', 'bar')
this.setContext('first', 'mario')
return true
},
function (detail) {
console.log('foo is', this.getContext('foo'))
return true
},
],
})
} When you visit Additionally, in the component, Here's the rationale behind this API design:
The only downside is that in this case, route pre-condition functions must be defined with the "old" What do you think? Feel free to play around with the |
Thinking more about it, maybe rather than passing the context's functions through |
@ItalyPaleAle The problem is actually more generic, as you already mentioned with the word "middleware". In my case, my Svelte components all accept real JS objects, not strings. However, the URL is a string, so it has an ID, and I need a function that translates the ID into an object, before calling the component. I do not want this mapping from ID to object to clutter the component, but I want to maintain a clean API for the component, independent from routing. Also all my components will need the same mapping from ID to object. With "svelte-routing", I can do, and this works:
and then PersonPage receives a proper person object. I cannot see a way with svelte-spa-router to achive the same. I am wondering whether I could just pass a function instead of a component, but I cannot figure out the API for the functions:
|
I would like to add my 2 cents in case it helps. I very much like the look of this library and plan on using it when I eventually migrate the company app from Angular to Svelte. We do not even have proper routing right now, but in the app I work on, I basically have a ton of custom reactive state. I extensively use key-value caches and subscribable lists of my own making that are like the Svelte store API, but they also pass an event saying if the list of, say, users was refreshed brand-new, or one was added, or one was updated, or one was deleted. This works very well for efficiently recomputing tables and other views as the user clicks around the app and deletes/modifies/creates things. Triggering a refresh, of say, the whole list of users from anywhere in the app updates the information for every user wherever they are currently displayed. We have lots of little information panels, which really should be pages with proper URL routing but are currently just maintained by JS history state, and every type of panel (user, team, drive, etc.) needs to reactively watch the item ID and update information whenever the item is changed from anywhere, or maybe switch to the "404"-esque state when the item is deleted. The takeaway being, at least in my use case, it is not so simple as "does this item exist when the route is instantiated"--it is more like "watch this item and reflect changes or immediately show a placeholder if it doesn't exist in the first place". In any case, because the final "page" component that is going to be showing the item corresponding to the ID ALREADY needs to subscribe to the ID and reflect changes, we just make every page responsible for showing the placeholder when the item it wants to show doesn't exist. It makes sense to have different placeholders per type of item and not just some generic "redirect to 404 page" route guard thrown in front of every route (we have many types of "things" in the system). This is a huge burden on me because of the amount of similar code, but that is the cost of tailoring UI and making things less generic and crappy for the user. If this sort of thing was to somehow be offloaded onto the router in a generic way, all of the sudden the router would need to know about things like "oh this item got updated, tell the page component" and "unsubscribe from said item when they navigate to a different sort of page". I think it is best the router simply be responsible for mapping URL->component and facilitate visual transitions between routes and whatnot, but let page components do all the heavy lifting and tell the user if the normal information cannot be displayed for some reason. Abstractions can be used to make similar placeholder code less tedious to share between page components. Your library does cater to single-page-apps which excel in very stateful, snappy, desktop-esque UI in exchange for slower load time thanks to a complex JavaScript code base for managing all that state. These sorts of apps should handle reactivity themselves because they can get arbitrarily complex when it comes to things like offline mode and queueing up lots of requests that may go through at any moment and must update the UI across-the-board when they do succeed. |
This is my use-case: I have a guard that checks if the the id for
/book/:id
is a correct id shape (which can have several shapes), the check function practically normalizes the id, so I'd like to send the normalized id to the component. if the id is not proper, then I show a 404 page. The normalized id is not visible in the url though.Is it possible to change the props with a guard function?
My current solution is that my component parses the
id
again, which seems wasteful.The text was updated successfully, but these errors were encountered: