]> git.ipfire.org Git - thirdparty/vuejs/router.git/commitdiff
feat(router): go, back and forward can be awaited
authorEduardo San Martin Morote <posva13@gmail.com>
Fri, 1 May 2020 09:35:07 +0000 (11:35 +0200)
committerEduardo San Martin Morote <posva13@gmail.com>
Fri, 1 May 2020 09:35:07 +0000 (11:35 +0200)
__tests__/router.spec.ts
src/router.ts

index 11287091bf13ee6d4e44efef40ffcf8e23a18f93..1d6c2a8c737279641215f10de16a28bc4d05bdfe 100644 (file)
@@ -176,6 +176,23 @@ describe('Router', () => {
     expect(router.currentRoute.value).not.toBe(START_LOCATION_NORMALIZED)
   })
 
+  it('can await router.go', async () => {
+    const { router } = await newRouter()
+    await router.push('/foo')
+    let currentRoute = router.currentRoute.value
+    const [p1, r1] = fakePromise()
+    router.beforeEach(async (to, from, next) => {
+      await p1
+      next()
+    })
+    let p = router.go(-1)
+    expect(router.currentRoute.value).toBe(currentRoute)
+    r1()
+    // resolves to undefined as a working navigation
+    await expect(p).resolves.toBe(undefined)
+    expect(router.currentRoute.value).not.toBe(currentRoute)
+  })
+
   it('can pass replace option to push', async () => {
     const { router, history } = await newRouter()
     jest.spyOn(history, 'replace')
index 4cabdfb41dd169e9ae0f14d4de702c67e3443b66..2795a42bb4ad2311806a741b0c9d33c876a279fc 100644 (file)
@@ -139,13 +139,11 @@ export interface Router {
 
   resolve(to: RouteLocationRaw): RouteLocation & { href: string }
 
-  push(to: RouteLocationRaw): Promise<NavigationFailure | void>
-  replace(to: RouteLocationRaw): Promise<NavigationFailure | void>
-  // TODO: return a promise when https://github.com/vuejs/rfcs/pull/150 is
-  // merged
-  back(): void
-  forward(): void
-  go(delta: number): void
+  push(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>
+  replace(to: RouteLocationRaw): Promise<NavigationFailure | void | undefined>
+  back(): Promise<NavigationFailure | void | undefined>
+  forward(): Promise<NavigationFailure | void | undefined>
+  go(delta: number): Promise<NavigationFailure | void | undefined>
 
   beforeEach(guard: NavigationGuardWithThis<undefined>): () => void
   beforeResolve(guard: NavigationGuardWithThis<undefined>): () => void
@@ -313,7 +311,7 @@ export function createRouter(options: RouterOptions): Router {
   function pushWithRedirect(
     to: RouteLocationRaw | RouteLocation,
     redirectedFrom?: RouteLocation
-  ): Promise<NavigationFailure | void> {
+  ): Promise<NavigationFailure | void | undefined> {
     const targetLocation: RouteLocation = (pendingLocation = resolve(to))
     const from = currentRoute.value
     const data: HistoryState | undefined = (to as RouteLocationOptions).state
@@ -346,7 +344,7 @@ export function createRouter(options: RouterOptions): Router {
     const toLocation = targetLocation as RouteLocationNormalized
 
     toLocation.redirectedFrom = redirectedFrom
-    let failure: NavigationFailure | void
+    let failure: NavigationFailure | void | undefined
 
     if (!force && isSameRouteLocation(from, targetLocation))
       failure = createRouterError<NavigationFailure>(
@@ -629,7 +627,7 @@ export function createRouter(options: RouterOptions): Router {
             (error as NavigationRedirectError).to,
             toLocation
           ).catch(() => {
-            // TODO: in dev show warning, in prod noop, same as initial navigation
+            // TODO: in dev show warning, in prod triggerError, same as initial navigation
           })
           // avoid the then branch
           return Promise.reject()
@@ -659,7 +657,7 @@ export function createRouter(options: RouterOptions): Router {
         )
       })
       .catch(() => {
-        // TODO: same as above: in dev show warning, in prod noop, same as initial navigation
+        // TODO: same as above
       })
   })
 
@@ -724,6 +722,25 @@ export function createRouter(options: RouterOptions): Router {
       .then(position => position && scrollToPosition(position))
   }
 
+  function go(delta: number) {
+    return new Promise<NavigationFailure | void | undefined>(
+      (resolve, reject) => {
+        let removeError = errorHandlers.add(err => {
+          removeError()
+          removeAfterEach()
+          reject(err)
+        })
+        let removeAfterEach = afterGuards.add((_to, _from, failure) => {
+          removeError()
+          removeAfterEach()
+          resolve(failure)
+        })
+
+        routerHistory.go(delta)
+      }
+    )
+  }
+
   const router: Router = {
     currentRoute,
 
@@ -736,9 +753,9 @@ export function createRouter(options: RouterOptions): Router {
 
     push,
     replace,
-    go: routerHistory.go,
-    back: () => routerHistory.go(-1),
-    forward: () => routerHistory.go(1),
+    go,
+    back: () => go(-1),
+    forward: () => go(1),
 
     beforeEach: beforeGuards.add,
     beforeResolve: beforeResolveGuards.add,