PolymerElements / app-route

A modular client-side router

Home Page:https://www.polymer-project.org/1.0/articles/routing.html

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Two data change events when app-routes chained.

diwalkerdev opened this issue · comments

Description

Chaining two app routes causes the second to fire two data change events when the route changes.

Expected outcome

Should only fire once.

Actual outcome

Fires twice.

Example code

<link rel="import" href="https://github.com/PolymerElements/bower_components/polymer/polymer.html" target="_blank" rel="nofollow">
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
<link rel="import" href="../../bower_components/app-route/app-route.html">
<link rel="import" href="../../bower_components/app=">

<dom-module id="app-route-app">
  <template>
    <style>
      :host {
        display: block;
      }
    </style>
    <h2>app-route bug demo</h2>
    
    <app-route
        route="{{route}}"
        pattern="/:page"
        data={{firstData}}
        tail="{{tail}}">
    </app-route>
    
    <app-route
        route="{{tail}}"
        pattern="/:page"
        data="{{data}}">
    </app-route>
        
    <paper-button raised on-tap="_setRoute">button</paper-button>
    
  </template>

  <script>
    Polymer({

      is: 'app-route-app',

      properties: {
        route: {
          type: Object,
          notify: true,
          value: function() {return {path: "", prefix:""}}
        },
            
        data: {
          type: Object,
          notify: true
        },
        
        firstData: {
          type: Object,
          notify: true
        },
        
        tail: {
          type: Object,
          notify: true
        },
      },
      
      observers: [
        "_onRouteChanged(route.*)",
        "_onFirstDataChanged(firstData.page)",
        "_onDataChanged(data.page)",
        "_onTailChanged(tail.*)"
      ],
      
      _setRoute: function(e) {
//        console.log("Setting route.");
        this.set("route.path", "/some/path/somewhere"); 
      },
      
      _onRouteChanged: function(newValue) {
//        console.log("Route changed: " + JSON.stringify(newValue));
      },
      
      _onDataChanged: function(newValue) {
        console.log("Data page changed: " + JSON.stringify(newValue));
      },
      
      _onFirstDataChanged: function(newValue) {
        console.log("First page changed: " + JSON.stringify(newValue));
      },
      
      _onTailChanged: function(newValue) {
//        console.log("Tail path changed: " + JSON.stringify(newValue));
      },

    });
  </script>
</dom-module>

Steps to reproduce

  1. Load the above example (consists of a page with a button that sets the route).
  2. Open developer tools and open the console.
  3. Clear any output and then click the button.
  4. You'll see the output:
First page changed: "some"
Data page changed: "path"
Data page changed: "path"

One data change for the top level app-route and then two events for the chained app-route.

Cause

Seems to be __tryToMatch function in app-route.html. Set a break point here before clicking the button, the debugger will stop once for the first app-route, the again for the second app-route. During this function the tail variable gets updated which calls __tailPathChanged which does this.set('route.path', newPath); which calls __tryToMatch for the third time. From what I can tell, __tryToMatch doesn't check that the data value has actually changed and we get the second update event - unlike the tail which is checked and so we don't get the second update event.

Browsers Affected

  • Chrome

@jfrazzano probably best not to ask that kind of a question in the middle of a bug report. You might have more success in the polymer slack channel

Related/duplicated: #173

duplicate. closing in favor of #173