Router DIY —Navigate somewhere

Ran Wahle
2 min readMay 12, 2019

--

After getting full control over our app’s navigation, let’s implement the mechanism that shows different screens according to our URL.

Let’s have a look at the data structure we’d like to have for our router, it is similar to the angular one

Here is an example of a route

{
path: '/addImage',
element: 'div',
attributes: {is: 'add-image'}
}

Let’s see the object’s members

  1. path: The relative path
  2. element: The element to render (could be a regular one or a custom one)
  3. attributes: Every attribute that should be set on the element, should go here. Please notice the “is” attribute in the example, it is crucial when we want to extend an element.

OK router, please render my element

In our code, rendering the element, will be done in a router-outlet component, that should contain the element being rendered, but here is what the router will do

navigate(url) {
try {
url = url === '/' ? url : new URL(url).pathname;
} catch (err) {
throw Error(`Cannot construct url from ${url}`)
}

this.currentSnapshot = this.routingSnapshotTreeBuilder.buildRouteTree(url);

history.pushState(null, null, url);

this.routerOutlet.setAttribute('current-url', url);
}

OK, router-outlet you said?

Yes, and here is the code on the router-outlet component

async changeRoute(newRoute) {

const newRouteData = module.Router.routingSnapshotTreeBuilder.buildRouteTree(newRoute);

if (!newRouteData) {
throw Error(`Could not build tree for ${newRoute}`);
}


module.Router.router.currentSnapshot = newRouteData;

this.clearChildren();

if (!newRouteData.attributes) {
newRouteData.attributes = {};
}
const newElement = document.createElement(newRouteData.element, newRouteData.attributes);

this.appendChild(newElement);
}

In here, you may find the entire router-outlet code.

Next, find route match.

--

--