Skip to content

Commit

Permalink
Fixes for async routes:
Browse files Browse the repository at this point in the history
1. If the page changes while a dynamic route is loading, do not display it when ready
2. Clone the detail object passed to the route loaded event for the placeholder component
  • Loading branch information
ItalyPaleAle committed Sep 20, 2020
1 parent bdae3a1 commit cf45241
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 12 deletions.
25 changes: 20 additions & 5 deletions Router.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -430,10 +430,15 @@ if (restoreScrollState) {
})
}
// Always have the latest value of loc
let lastLoc = null
// Handle hash change events
// Listen to changes in the $loc store and update the page
// Do not use the $: syntax because it gets triggered by too many things
loc.subscribe(async (newLoc) => {
lastLoc = newLoc
// Find a route matching the location
component = null
let i = 0
Expand Down Expand Up @@ -463,16 +468,26 @@ loc.subscribe(async (newLoc) => {
component = obj.loading
componentParams = obj.loadingParams
// Add the component object and name to the detail object
detail.component = component
detail.name = component.name
// Trigger the routeLoaded event for the loading component
dispatchNextTick('routeLoaded', detail)
// Create a copy of detail so we don't modify the object for the dynamic route (and the dynamic route doesn't modify our object too)
dispatchNextTick('routeLoaded', {
route: routesList[i].path,
location: newLoc.location,
querystring: newLoc.querystring,
userData: routesList[i].userData,
component: component,
name: component.name
})
}
// Invoke the Promise
const loaded = await obj()
// Now that we're here, check if we still want this component, as the user might have navigated to another page in the meanwhile
if (newLoc != lastLoc) {
break
}
// If there is a "default" property, which is used by async routes, then pick that
component = (loaded && loaded.default) || loaded
Expand Down
16 changes: 11 additions & 5 deletions test/app/src/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,20 @@ import Regex from './routes/Regex.svelte'
import NotFound from './routes/NotFound.svelte'

const wrappedLuckyRoute = wrap({
asyncRoute: () => import('./routes/Lucky.svelte').then((res) => {
return new Promise((resolve) => {
setTimeout(() => resolve(res), 2000)
})
}),
// Add an artificial delay so we can experience the route loading
asyncRoute: () => import('./routes/Lucky.svelte')
.then((res) => {
return new Promise((resolve) => {
setTimeout(() => resolve(res), 2000)
})
}),
// Component to show while the module is being downloaded
loadingRoute: Loading,
// Props for the loading component
loadingParams: {message: 'secret'},
// Set some user data
userData: {foo: 'bar'},
// Route pre-conditions, which are executed in order
conditions: [
(detail) => {
// If there's a querystring parameter, override the random choice (tests need to be deterministic)
Expand Down
4 changes: 2 additions & 2 deletions test/cases/01-routing.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -323,12 +323,12 @@ describe('<Router> component', function() {
.expect.element('#pleasewait').text.to.equal('Please wait…')
browser.expect.element('#loadingmessage').text.to.equal('Message is secret')
browser.waitForElementPresent('#lucky')
.expect.element('#logbox').text.to.equal('routeLoading - {"route":"/lucky","location":"/lucky","querystring":"pass=1","userData":{"foo":"bar"},"name":"Loading"}\nrouteLoaded - {"route":"/lucky","location":"/lucky","querystring":"pass=1","userData":{"foo":"bar"},"name":"Loading"}\nrouteLoaded - {"route":"/lucky","location":"/lucky","querystring":"pass=1","userData":{"foo":"bar"},"name":"Lucky"}')
.expect.element('#logbox').text.to.equal('routeLoading - {"route":"/lucky","location":"/lucky","querystring":"pass=1","userData":{"foo":"bar"}}\nrouteLoaded - {"route":"/lucky","location":"/lucky","querystring":"pass=1","userData":{"foo":"bar"},"name":"Loading"}\nrouteLoaded - {"route":"/lucky","location":"/lucky","querystring":"pass=1","userData":{"foo":"bar"},"name":"Lucky"}')

// Condition always fails
browser.url(browser.launchUrl + '/#/lucky?pass=0')
.waitForElementPresent('#logbox')
.expect.element('#logbox').text.to.equal('routeLoading - {"route":"/lucky","location":"/lucky","querystring":"pass=1","userData":{"foo":"bar"},"name":"Loading"}\nrouteLoaded - {"route":"/lucky","location":"/lucky","querystring":"pass=1","userData":{"foo":"bar"},"name":"Loading"}\nrouteLoaded - {"route":"/lucky","location":"/lucky","querystring":"pass=1","userData":{"foo":"bar"},"name":"Lucky"}\nconditionsFailed - {"route":"/lucky","location":"/lucky","querystring":"pass=0","userData":{"foo":"bar"}}\nrouteLoading - {"route":"/wild/*","location":"/wild/conditions-failed","querystring":""}\nrouteLoaded - {"route":"/wild/*","location":"/wild/conditions-failed","querystring":"","name":"Wild"}')
.expect.element('#logbox').text.to.equal('routeLoading - {"route":"/lucky","location":"/lucky","querystring":"pass=1","userData":{"foo":"bar"}}\nrouteLoaded - {"route":"/lucky","location":"/lucky","querystring":"pass=1","userData":{"foo":"bar"},"name":"Loading"}\nrouteLoaded - {"route":"/lucky","location":"/lucky","querystring":"pass=1","userData":{"foo":"bar"},"name":"Lucky"}\nconditionsFailed - {"route":"/lucky","location":"/lucky","querystring":"pass=0","userData":{"foo":"bar"}}\nrouteLoading - {"route":"/wild/*","location":"/wild/conditions-failed","querystring":""}\nrouteLoaded - {"route":"/wild/*","location":"/wild/conditions-failed","querystring":"","name":"Wild"}')

browser.end()
})
Expand Down

0 comments on commit cf45241

Please sign in to comment.