Polymer / pwa-starter-kit

Starter templates for building full-featured Progressive Web Apps from web components.
https://pwa-starter-kit.polymer-project.org
2.37k stars 431 forks source link

how to use dynamic routes ? #236

Closed HeratPatel closed 6 years ago

HeratPatel commented 6 years ago

I want to use dynamic routes like... /item/:id

how can I use it ?

kr05 commented 6 years ago

Have you tried any particular solution or made any attempts at implementing dynamic routes? If you can provide more information about your specific situation we can do more to help! In the meantime, I'll try to give you some general ideas to get you started.

Fortunately, the pwa-starter-kit template has already done most of the heavy lifting. They leverage a tiny helper method called router.js, which exposes a method called installRouter. What it does is self-explanatory: it "installs" a listener, which calls a method you provide every time the route changes. Here's what it looks like in the template:

firstUpdated() {
    installRouter((location) => this._locationChanged(location));
}

Here's the _locationChanged method, which is called every time the route changes:

_locationChanged() {
    const path = window.decodeURIComponent(window.location.pathname);
    const page = path === '/' ? 'view1' : path.slice(1);
    this._loadPage(page);
}

This is where we'll introduce the changes we need to implement dynamic routing. We have to somehow extract the id from our current location and load the appropiate view. This is an example of how you might achieve that:

_locationChanged() {
   const path = window.decodeURIComponent(window.location.pathname);
   const page = path === '/' ? 'view1' : path.slice(1);
   const id = this.extractItemIdFromPath(path);

   if (id) {
      this._loadItemDetails(id);
   } else {
      this._loadPage(page);     
   }
}

_loadItemDetails(id) {
   import('../components/item-details.js').then((module) => {
      //This is not strictly necessary, but if you load the item details from within
      //the element, this is one way in which you can pass the item id
      this.shadowRoot.querySelector('#itemDetails').itemID = id;
   });
    this._page = `item/${id}`;
}

The extractItemIdFromPath method has to be implemented by you, as it will be different for every use case. The last step is to actually trigger the route change. Assuming you want open the item details view by dispatching an event after a user taps on something:

_onItemClick(e) {
    const id = e.detail; //or e.detail.id, depending on how you constructed the CustomEvent
   window.history.pushState({}, '', `/${item.__id__}/details`);
   this._locationChanged();
}

Hopefully this clears some things up regarding dynamic routing!

HeratPatel commented 6 years ago

thank you so much @kr05 it is very helpful to me