krasimir/navigo

Routing hooks error

Wayfindertm opened this issue · 10 comments

router.hooks({
	before(done, match) {
		console.log('Before hook');
		router.navigate("/auth", {callHooks: false});
		done();
	}
});
router
	.on('/', () => {
		console.log('Home');
	})
	.on('/auth', () => {
		console.log('Auth');
	});

And when we call home route we see in console:

Before hook
Home
Auth

How can a force open auth without calling home?

You should not call the done callback in the before hook. This basically means "keep going and resolve the routes". You either don't call it or you call it with false (done(false)). Here's a test case that shows how it works https://github.com/krasimir/navigo/blob/master/src/__tests__/hooks.spec.ts#L58-L74

So if i remove done(), router.navigate will not work?

Hm ... interesting. Can you try with done(false).

Before hook

Thats all (((

Sorry, I did not look at your code in details. So what is happening is that you are defining a hook for every route. Including /auth. Which means that you successfully navigate to it but the before hook kicks in because we are doing done(false) we can't continue and call the handler. The proper implementation will look like so:

router
  .on('/auth', () => {
    console.log('Auth');
  });
  .on('/', () => {
    console.log('Home');
  }, {
    before(done) {
      router.navigate("/auth");
      done(false);
    }
  })

The callHooks option is I'm afraid only when you have a route specific hooks.

Your code dosn't work too

And this code too:

router.hooks({
	before(done, match) {
		console.log(match.url);
		if (match.url !== 'auth') {
			console.log('Before hook');
			router.navigate("/auth");
			done(false);
		} else {
			done();
		}
	}
});

I need to make something like middleware to check auth, so i want use global hook for all routes except auth

I see. let me come with a test case.

Hey @Wayfindertm,

there was a bug which is fixed in a new 8.10.0 version. Can you please try it and let me know how it works. Here's the test case:

describe("and we want to navigate out from a hook", () => {
  it("should properly land on the new path", () => {
    const r: NavigoRouter = new Navigo();
    const h1 = jest.fn();
    const h2 = jest.fn();
    r.hooks({
      before(done, match) {
        if (match.url !== "auth/sign-in") {
          r.navigate("/auth/sign-in");
          done(false);
        } else {
          done();
        }
      },
    });
    r.on("/auth/sign-in", h1);
    r.on("/", h2);

    r.resolve();

    expect(h1).toBeCalledTimes(1);
    expect(h2).not.toBeCalled();
  });
});

It works great!!! Thanx!!!