Search code examples
htmlpolymer

Problems with polymer-starter-kit linking pages


I've been adapting the polymer-starter-kit for a project, and there is one thing I just can't get my head around, it's very simple too.

I'm trying to access a custom element using iron-pages.

Here is the code for my app:

<!--
@license
Copyright (c) 2016 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->

<link rel="import" href="../bower_components/polymer/polymer-element.html">
<link rel="import" href="../bower_components/app-layout/app-drawer/app-drawer.html">
<link rel="import" href="../bower_components/app-layout/app-drawer-layout/app-drawer-layout.html">
<link rel="import" href="../bower_components/app-layout/app-header/app-header.html">
<link rel="import" href="../bower_components/app-layout/app-header-layout/app-header-layout.html">
<link rel="import" href="../bower_components/app-layout/app-scroll-effects/app-scroll-effects.html">
<link rel="import" href="../bower_components/app-layout/app-toolbar/app-toolbar.html">
<link rel="import" href="../bower_components/app-route/app-location.html">
<link rel="import" href="../bower_components/app-route/app-route.html">
<link rel="import" href="../bower_components/iron-pages/iron-pages.html">
<link rel="import" href="../bower_components/iron-selector/iron-selector.html">
<link rel="import" href="../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="my-icons.html">

<link rel="lazy-import" href="my-view1.html">
<link rel="lazy-import" href="my-view2.html">
<link rel="lazy-import" href="my-view3.html">
<link rel="lazy-import" href="iss-supervisor-login.html">
<link rel="lazy-import" href="my-view404.html">

<dom-module id="iss-supervisor-app">
  <template>
    <style>
      :host {
        --app-primary-color: #002d56;
        --app-secondary-color: black;

        display: block;
      }

      app-drawer-layout:not([narrow]) [drawer-toggle] {
        display: none;
      }

      app-header {
        color: #fff;
        background-color: var(--app-primary-color);
      }

      app-header paper-icon-button {
        --paper-icon-button-ink-color: white;
      }

      .drawer-list {
        margin: 0 20px;
      }

      .drawer-list a {
        display: block;
        padding: 0 16px;
        text-decoration: none;
        color: var(--app-secondary-color);
        line-height: 40px;
      }

      .drawer-list a.iron-selected {
        color: black;
        font-weight: bold;
      }

      .logo {
        width: 100px;
        height: auto;
      }
    </style>

    <app-location route="{{route}}" url-space-regex="^[[rootPath]]"></app-location>
    <app-route
        route="{{route}}"
        pattern="[[rootPath]]:page"
        data="{{routeData}}"
        tail="{{subroute}}"></app-route>

    <app-drawer-layout fullbleed narrow="{{narrow}}">
      <!-- Drawer content -->
      <app-drawer id="drawer" slot="drawer" swipe-open="[[narrow]]">
        <app-toolbar>Menu</app-toolbar>
        <iron-selector selected="[[page]]" attr-for-selected="name" class="drawer-list" role="navigation">
          <a name="login" href="/login">New View</a>
          <a name="view1" href="/view1">View One</a>
          <a name="view2" href="[[rootPath]]view2">View Two</a>
          <a name="view3" href="[[rootPath]]view3">View Three</a>
        </iron-selector>
      </app-drawer>

      <!-- Main content -->
      <app-header-layout has-scrolling-region>

        <app-header slot="header" condenses reveals effects="waterfall">
          <app-toolbar>
            <paper-icon-button icon="my-icons:menu" drawer-toggle></paper-icon-button>
            <img class="logo" src="/../images/logo.jpg">
            <div main-title>Access 365 - Supervisor</div>
          </app-toolbar>
        </app-header>

        <iron-pages
            selected="[[page]]"
            attr-for-selected="name"
            fallback-selection="view404"
            role="main">
          <iss-supervisor-login name="login"></iss-supervisor-login>
          <my-view1 name="view1"></my-view1>
          <my-view2 name="view2"></my-view2>
          <my-view3 name="view3"></my-view3>
          <my-view404 name="view404"></my-view404>
        </iron-pages>
      </app-header-layout>
    </app-drawer-layout>
  </template>

  <script>
    class IssSupervisorApp extends Polymer.Element {
      static get is() { return 'iss-supervisor-app'; }

      static get properties() {
        return {
          page: {
            type: String,
            reflectToAttribute: true,
            observer: '_pageChanged',
          },
          routeData: Object,
          subroute: String,
          // This shouldn't be neccessary, but the Analyzer isn't picking up
          // Polymer.Element#rootPath
          rootPath: String,
        };
      }

      static get observers() {
        return [
          '_routePageChanged(routeData.page)',
        ];
      }

      _routePageChanged(page) {
        // If no page was found in the route data, page will be an empty string.
        // Deault to 'view1' in that case.
        this.page = page || 'view1';

        // Close a non-persistent drawer when the page & route are changed.
        if (!this.$.drawer.persistent) {
          this.$.drawer.close();
        }
      }

      _pageChanged(page) {
        // Load page import on demand. Show 404 page if fails
        var resolvedPageUrl = this.resolveUrl('my-' + page + '.html');
        Polymer.importHref(
            resolvedPageUrl,
            null,
            this._showPage404.bind(this),
            true);
      }

      _showPage404() {
        this.page = 'view404';
      }
    }

    window.customElements.define(IssSupervisorApp.is, IssSupervisorApp);
  </script>
</dom-module>

Here is the code for the element I'm trying to insert:

<!-- Load the Polymer.Element base class -->
<link rel="import" href="../bower_components/polymer/polymer-element.html">

<dom-module id="iss-supervisor-login">
  <!-- Defines the element's style and local DOM -->
  <template>
    <style>
      :host {
        display: block;

        padding: 16px;
      }
    </style>

    <h1>New view</h1>
  </template>
  <script>
    // Your new element extends the Polymer.Element base class
    class IssSupervisorLogin extends Polymer.Element {
      static get is() { return 'iss-supervisor-login'; }
    }
    //Now, register your new custom element so the browser can use it
    customElements.define(IssSupervisorLogin.is, IssSupervisorLogin);
  </script>
</dom-module>

The thing that's really frustrating me is that I got this to work using the tutorial, and after a few name changes I can't get it to work. Whenever I try to switch the page, I get the default 404 error page. Can anyone help me out?


Solution

  • <iron-selector selected="[[page]]" attr-for-selected="name" class="drawer-list" role="navigation">
          <a name="login" href="/login">New View</a>
          <a name="view1" href="/view1">View One</a>
          <a name="view2" href="[[rootPath]]view2">View Two</a>
          <a name="view3" href="[[rootPath]]view3">View Three</a>
    </iron-selector>
    

    The name attribute above is used to import/load the page you are viewing.

    var resolvedPageUrl = this.resolveUrl('my-' + page + '.html');
    

    So, when you try to load iss-supervisor-login.html page. It will load my-login.html which is not found so you got 404 error.

    You need to change according to your page name in name attribute and the variable resolvedPageUrl.