title: How to route from an <iron-ajax> callback
body: <p>Given a root component in <code>index.html</code> (<code>my-app</code>) containing <code>iron-pages</code>, and an <code>iron-ajax</code> call inside one or more of those pages, what is the best way for an <code>iron-ajax</code> <code>on-response</code> function in a child component to tell <code>my-app</code> to change the route? I am using Polymer 2. I see examples relying on links in different components, and calls in the same component, but no <code>iron-ajax</code> from one component to its parent.</p>
  
  <p>In <code>my-app.html</code> I have an <code>app-location</code> and <code>app-route</code>, and the <code>iron-pages</code>:</p>
  
  <pre><code>&lt;app-location route="{{route}}"&gt;&lt;/app-location&gt;
  &lt;app-route
    route="{{route}}"
    pattern="/:page"
    data="{{routeData}}"
    tail="{{subroute}}"&gt;&lt;/app-route&gt;
  
  &lt;app-toolbar&gt;...
  
  &lt;iron-pages role="main" selected="[[routeData.page]]" 
      attr-for-selected="name" selected-attribute="visible" 
      fallback-selection="404"&gt;
    &lt;my-login name="" route="[[subroute]]"&gt;&lt;/my-login&gt;
    &lt;my-todos name="my-todos" route="[[subroute]]"&gt;&lt;/my-todos&gt;
    ...
    &lt;my-404-warning name="404"&gt;&lt;/my-404-warning&gt;
  &lt;/iron-pages&gt;
  </code></pre>
  
  <p>The user first sees <code>my-login</code>. When the <code>iron-ajax</code> in <code>my-login</code> call completes, I want to replace <code>my-login</code> with <code>my-todos</code>. I’ve come up with two approaches so far (see below). Both work--changing the page and updating the URL--but is one necessarily better? Is there a cleaner approach I’ve not found?</p>
  
  <p>The <code>iron-ajax</code> on-response handler in <code>my-login</code></p>
  
  <pre><code>_handleLogin(e) {
    if (e.detail.response) {
      let loginInfo = e.detail.response;
      if (loginInfo.o_error) {
        console.log('login error: '+loginInfo.o_error);
        // ...
      } else {
        this.dispatch('login', loginInfo); // to polymer-redux store
  
        // UPDATE PATH, OPTION #1
        var page = this.ownerDocument.body.children[0];
        page.set('route.path', 'server-catalog');
  
        // UPDATE PATH, OPTION #2
        this.dispatchEvent(new CustomEvent('change-route', {
           bubbles: true, composed: true, detail: "my-todos" }));
  
        // UPDATE PATH, OPTION #3..n
        ???
      }
    } else {
      console.log(e.detail);
    }
  }
  </code></pre>
  
  <p>Both options trigger the observer, <code>_routePageChanged(routeData.page)</code>, and so the magic proceeds.</p>
  
  <p>Option #1 is straightforward, but involves reaching directly into the parent, my-app.</p>
  
  <p>Option #2 relies on two additions to <code>my-app</code>:</p>
  
  <pre><code>ready() {
    super.ready();
    // Custom elements polyfill safe way to indicate an element has been upgraded.
    this.removeAttribute('unresolved');
    // listen for custom events
    this.addEventListener('change-route', (e)=&gt;this._onChangeRoute(e));
  }
  
  _onChangeRoute(e) {
    this.set('route.path', e.detail);
  }
  </code></pre>
  
  <p>Option #2 feels better, but I’m wondering if it’s the cleanest I can do.</p>