Comments (15)
@hmmhmmhm @frederikhors @joshua1 @BogdanDarius (tagging everyone who ever asked about this feature)
sorry this took SO LONG.
I finally managed to get a working prototype of this, in the dynamic-import branch.
It works by creating the wrapAsync
method to wrap the route:
import {wrapAsync} from '../../Router.svelte'
export default {
'/async': wrapAsync(() => import('./Async.svelte')
}
(Note that you must use a function definition, such as () => import('foo')
and not import('foo')
, which is an invocation)
Then it should just work 😄
The only thing I'd love your input on is on how to handle the "loading" state. Right now, I've created another event called routeLoading
that is emitted when the route starts loading. However, the router on its own does not display anything while the route is loading (for now, it just shows the previous route). Sadly, returning a Promise isn't possible.
I have a few options I'm considering:
- Make developers listen to the
routeLoading
and thenrouteLoaded
events to manually handle the state of the route loading asynchronously - The router could export a named slot "loading" that will be used to display temporary content, such as this:
<Router {routes}> <div slot="loading"> Show something while the route is loading </div> </Router>
- The route definition object could have a new convention for a route named "loading", such as:
import {wrapAsync} from '../../Router.svelte' export default { '/async': wrapAsync(() => import('./Async.svelte'), '*': NotFound, 'loading': Loading, }
What are your thoughts on the above?
I'm leaning towards option 3 as that seems the most idiomatic to this router. But would like to hear your thoughts.
I'm also open to suggestions on other ways this can be implemented.
from svelte-spa-router.
I've updated the dynamic-import
branch and now there's a single wrap
function exposed in svelte-spa-router/wrap
which takes an object as argument, and allows dynamically-imported and not routes. 🎉
(The wrap
function exported by svelte-spa-router
is still available as an interface for backwards compatibility, but now marked as deprecated, and I'll remove it from 4.0)
Thanks a lot for your feedback @frederikhors and @BogdanDarius. I think this will work and I'll merge it into the 3.0-wip branch.
This will be the major new release for the router v3, which I plan to finish ASAP :)
from svelte-spa-router.
Thanks a lot for testing it and confirming it works!
Good point. A different loading view for each component was not a requirement I had considered. But it makes sense.
Doing that would not be possible with the options above (maybe with 1). It would require people to manually determine the loader to show, for example by using the $location store to know what component will be loaded.
The only way to do that in the router would be to use option 5:
- Adding the loader as an argument in
wrapAsync
, such aswrapAsync(() => import('foo'), LoaderComponent1
)
from svelte-spa-router.
I like the idea of having it as an argument to wrapAsync
.
from svelte-spa-router.
Thanks @BogdanDarius for the feedback!
The dynamic-import branch has been updated and now the wrapAsync
function accepts a component to display while loading the route. If nothing is passed (or a false-y value), then nothing is displayed.
@hmmhmmhm @frederikhors what do you think?
from svelte-spa-router.
It would have to be more like {component: LoaderComponent, props}
but could work. Let me look into that, and if it's possible to support both that and just LoaderComponent
.
As an alternative, because the signature is getting complicated enough already, I could simply make wrap
and wrapAsync
accept an object with parameters. That would also be more future-proof, and I'm more leaning towards that.
from svelte-spa-router.
Still not possible, sorry. I ran into some issues when trying to implement that, and it is in the backlog. PRs are welcome :)
from svelte-spa-router.
Maybe I can find time to look up about this this this weekend. If I don't work overtime...
from svelte-spa-router.
@hmmhmmhm it would be amazing. As writed here: #104:
Looking at yrv
router (a good router!) we can see two ways of importing routes:
<Router>
<Route exact path="/promise" component={import('path/to/other-component.svelte')}/>
<Route exact path="/lazy" component={() => import('path/to/another-component.svelte')}/>
</Router>
With https://github.com/ItalyPaleAle/svelte-spa-router/blob/master/Advanced%20Usage.md#async-route-loading we have just the lazy one. Am I correct?
I think it would be useful (and amazing) to have both in svelte-spa-router
(three-shaked if we do not use them).
The promise way I think is amazing because I can have a lot of routes and maybe I just need to load immediately just the one I need and after that in background start downloading others.
What do you think about?
from svelte-spa-router.
@frederikhors What you said is a different issue from wrap.
Since you left an issue in my report, I will answer it here hmmhmmhm/svelte-spa-chunk#3.
from svelte-spa-router.
@hmmhmmhm @frederikhors @joshua1 @BogdanDarius (tagging everyone who ever asked about this feature)
sorry this took SO LONG.I finally managed to get a working prototype of this, in the dynamic-import branch.
It works by creating the
wrapAsync
method to wrap the route:import {wrapAsync} from '../../Router.svelte' export default { '/async': wrapAsync(() => import('./Async.svelte') }(Note that you must use a function definition, such as
() => import('foo')
and notimport('foo')
, which is an invocation)Then it should just work
The only thing I'd love your input on is on how to handle the "loading" state. Right now, I've created another event called
routeLoading
that is emitted when the route starts loading. However, the router on its own does not display anything while the route is loading (for now, it just shows the previous route). Sadly, returning a Promise isn't possible.I have a few options I'm considering:
- Make developers listen to the
routeLoading
and thenrouteLoaded
events to manually handle the state of the route loading asynchronously- The router could export a named slot "loading" that will be used to display temporary content, such as this:
<Router {routes}> <div slot="loading"> Show something while the route is loading </div> </Router>- The route definition object could have a new convention for a route named "loading", such as:
import {wrapAsync} from '../../Router.svelte' export default { '/async': wrapAsync(() => import('./Async.svelte'), '*': NotFound, 'loading': Loading, }What are your thoughts on the above?
I'm leaning towards option 3 as that seems the most idiomatic to this router. But would like to hear your thoughts.
I'm also open to suggestions on other ways this can be implemented.
Awesome!
I tested wrapAsync
on a bigger project, it works as expected.
Regarding the loading I agree that option 3 seems to most intuitive. I do have a question though, could you setup different loaders for some routes or just a single loader for all routes?
from svelte-spa-router.
Awesome work.
I tested the updated branch, it works as expected.
I find it very clean to include the loader component in the wrapAsync
, that is my take on it.
from svelte-spa-router.
Sorry for my delay in replying.
Great job, @ItalyPaleAle, as always. I haven't tested it yet because I don't have time right now but I trust and know it will work.
Personally I agree with the idea number 5 (passing the loading component as an argument of wrapAsync
) because very often we need to have different loaders based on what we are loading, but I also need to pass props to it.
Example:
const routes = new Map()
.set('/home', PageHome)
.set('/async', wrapAsync(() => import('Players.svelte'), LoaderComponent, {loader: props}))
Can we do something like that?
from svelte-spa-router.
@frederikhors thanks for the feedback!
The problem with the syntax you're suggesting is that the wrapAsync
's function signature is based on the wrap
's one: wrap(route, userData, ...conditions)
. userData
is an object too, so if we need to pass another object for the props for the loader component, that would be an issue...
from svelte-spa-router.
Can we use an obj like:
{ LoaderComponent, props }
?
Like:
const routes = new Map()
.set('/home', PageHome)
.set('/async', wrapAsync(() => import('Players.svelte'), { LoaderComponent, props })
from svelte-spa-router.
Related Issues (20)
- Nested routes as maps HOT 1
- If I want to go to the login page in the sidebar + SPA form, is it possible with route guard? HOT 4
- Is this not possible in routeLoaded? HOT 5
- What is the black bar in this image? HOT 2
- Feature request: Svelte 4 support HOT 13
- FEATURE REQUEST: pass next() in precondition to decide whether the router should *change* the current route HOT 1
- Load user data HOT 4
- How to check hash-bashed history HOT 1
- Is there an alternative to the "Failed to fetch dynamically import problem" issue in Vite + Svelte spa environment? HOT 1
- WARNING: The following packages have a svelte field in their package.json but no exports condition for svelte. [email protected] HOT 8
- Typescript problematic types after "wrapping" the route HOT 2
- navigating within same component does not work HOT 5
- Typescript support: Package path ./wrap is not exported from package svelte-spa-router HOT 2
- Will the library support Svelte 5? HOT 5
- Authentication and Authorization HOT 6
- Layouts not exists for svelte-spa-router? HOT 6
- Feature request: Nested route priority HOT 1
- children router bug HOT 2
- <Pages> was created with unknown prop 'params' HOT 4
- Typescript complaining about `Type 'WrappedComponent' is not assignable to type 'typeof SvelteComponent<any>'.ts(2322)` HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from svelte-spa-router.