Polymer: this.$ returns undefined in ready callback

Created on 24 Nov 2016  Â·  12Comments  Â·  Source: Polymer/polymer

Description

this.$ resolves to undefined in the ready lifecycle callback in a component in Chrome. After testing out many things the problem only happens in one component that is part of iron-pages. It happens after the browser directly reloads on that page, but it is not there when the page is accessed from another page. The app works in firefox as expected.

The code is generated from polymer-cli, application template.

<app-location route="{{route}}"></app-location> <app-route route="{{route}}" pattern="/:page" data="{{routeData}}" tail="{{subroute}}"></app-route> <app-route route="{{subroute}}" pattern="/:id" data="{{subrouteData}}"> </app-route>

<iron-pages selected="[[page]]" attr-for-selected="name" fallback-selection="view404" role="main"> <my-page name="test-plan-page" route="{{route}}" plan-id="{{subrouteData.id}}" id-test-case-path="{{idTestCasePath}}"></my-page> .... </iron-pages>

After removing all of the code from the component and just leaving the imports the bug is still there. Only after leaving three imports and if one of the imports is not vaadin-grid the page works. Even if I remove vaadin-grid and leave the rest of the imports the bug is still there and this.$ remains undefined. This is really weird.

(for some reason html tags are removed from markup so I have removed the opening symbol)

`link rel="import" href="../../bower_components/polymer/polymer.html">
link rel="import" href="../../bower_components/paper-fab/paper-fab.html">
link rel="import" href="../../bower_components/paper-input/paper-input.html">
link rel="import" href="../../bower_components/paper-input/paper-textarea.html">
link rel="import" href="../../bower_components/vaadin-grid/vaadin-grid.html">
link rel="import" href="../../bower_components/paper-menu-button/paper-menu-button.html">
link rel="import" href="../../bower_components/paper-item/paper-item.html">
link rel="import" href="../shared-styles.html">

dom-module id="my-page">
template>
Lorem ipsum
/template>

<script>
    Polymer({
        is: 'my-page',

        ready: function () {
            console.log(this.$);
        }
    });
</script>

/dom-module>

All of my other page components work and most have vaadin-grid working flawlessly.

Live Demo

Unable to give you the demo as the script is hosted locally and I'm unable to reproduce it separately.

Steps to Reproduce

Using chrome

  1. My app is generated using polymer-cli
  2. my-page is located as a page in iron-pages and has a ready callback
  3. Upon refreshing the browser with that page selected this.$ resolves to undefined
  4. If I navigate to the page from another page it works as expected.

Note: Once website is loaded from a different page everything is normal.

Expected Results

It should return an object with all DOM references by id.

Actual Results

Returns undefined

Browsers Affected

  • [x ] Chrome
  • [ ] Firefox - Works as expected
  • [ ] Edge
  • [ ] Safari 9
  • [ ] Safari 8
  • [ ] IE 11

Versions

  • Polymer: v1.7.0
  • webcomponents: v0.7.22
1.x pending-response

Most helpful comment

@vasstavr You need to call super.ready(): http://jsbin.com/cefiyuqixu/edit?html,console,output For more info see #4529 and #4412

All 12 comments

This might be a dup of issue #4160

I don't think so as I'm trying to access it in the ready callback and I'm using Polymer 170.

Can't reproduce. Go to polymer.html and look into _marshalIdNodes: this is there nodes are assigned to $. Try to debug what's happening there in your case.

Ok so I've recorded the video of the issue.

https://giant.gfycat.com/GrayFickleKudu.webm

In the video I'm logging state from:

  1. iron-pages _selectedPageChanged console.log(selected, old)
  2. _pageChanged: function (page) {
    let resolvedPageUrl = this.resolveUrl('components/' + page + '.html');
    console.log(resolvedPageUrl);
    this.importHref(resolvedPageUrl, null, this._showPage404, true);
    },
  3. In _marshalIdNodes if (this.nodeName === 'TEST-PLAN-PAGE') { console.log(this); };

So you can clearly see that for some reason the polymer element is not initialized (marshalIdNodes console.log is never outputted) for some reason when the browser is refreshed on the page, even though the iron-pages outputs correct page, the page is resolved properly and imported and the code from ready callback is executed (the undefined part). When the page is accessed from another it is initialized properly.

Firefox is still working properly.

Ok so the problem was with the polymer generated method in starter kit.

_routePageChanged: function(page) { this.page = page || 'view1'; },

Removing the OR condition solved it. Leaving it was causing that page to bug out and either not get properly initialized, or not get initialized at all (not sure which). In case of this particular page it was always defaulting and initializing view1 even though the page was selected in iron-pages and it's ready callback was obviously being triggered. This was isolated to only this page and like I've described in the original issue the problem could be resolved by removing imports until there was three, and one of them was not vaadin-grid - weird thing indeed. Everthing worked fine in Firefox.

Logging output all trough polymer I couldn't pinpoint what was the underlying issue, but I'm not sure if this is polymer (although it seems like it is) or the routing element or something else.

If you guys need further info let me know.

How are you using the Vadin grids?

Are you laying out all your pages?

And what version of Polymer?

I ask because I had a similar issue with iron pages caused by the way I prefer to keep data and repeat visual presentations

I mapped large value objects and had my own selectedView API that would only layout what was visible and I held state in the maps, lining up the potential next set of potential views updating duplicate data way way behind the scenes in inline promises and via a blobject

It made iron pages nuts

The first page some times would just not be there after initial load; tap a new tab or scroll view out and it lost the "element" Really the it lost the data that for my use cases was indistinguishable from the view. Iron pages had no idea stuff was lost.

I worked around it in 1.2--1.5, using the array selector, which I loved--and with a set of factory arrays and templatized shards of templates that I just put in the Dom myself

It let me fill up to 25 2500 box grids with literally 100,000s of thousands of data points

But I had to know the state of everything, to keep the grid data running, which included my own more active approach to object garbage collection

Since I was calling new over and over to fill my views, I would crush the ai buffers that map for browsers

Plus the movement of firstchildelemebt to parent node in the w3 spec made it so that independent management children required and still requires web wide, independent handling of first child

So, the point, if grids are stressing the browser ai to manage garbage and build your nodes from their own indexes/uri shards

You will lose first pages in traditional show me/hide you template scenarios (just worked around issue in a string literal template project--if I put all my Dom in the Dom-and then parsed for myself I had to take special care of first child/any deviation from a well patterned tree

If the grids are stressing your browser cache which the animation spinning waiting thing we indicated (they make it worse actually, especially if you don't unify your event handlers and keep them at bay)

You're going to lose stuff in the Dom for a while

My guess is vaadin is causing the stress aware of it and has a limited work around

Those limits were surpassed when you were importing a lot of junk

The work around there is to 1. Recognize your imports trickle down (usually) so If parents or pseudo parents in the treeAPi.

Sent from my iPhone

On Nov 25, 2016, at 9:20 AM, lnenad notifications@github.com wrote:

Ok so the problem was with the polymer generated method in starter kit.

_routePageChanged: function(page) { this.page = page || 'view1'; },
Removing the OR condition solved it. Leaving it was causing that page to bug out and either not get properly initialized, or not get initialized at all (not sure which). In case of this particular page it was always defaulting and initializing view1 even though the page was selected in iron-pages and it's ready callback was obviously being triggered. This was isolated to this page and like I've described in the original issue the problem could be resolved by removing imports until there was three, and one of them was not vaadin-grid - weird thing indeed.

Logging output all trough polymer I couldn't pinpoint what was the underlying issue, but I'm not sure if this is polymer (although it seems like it is) or the routing element or something else.

If you guys need further info let me know.

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or mute the thread.

I'm using 1.7, and I have nowhere near that amount of data in the page that was causing problems. I've tens of rows with a couple of columns. I don't think this was stress related as the app is still very light and I see no reason that it would cause any issues in browser gc.

@lnenad Are you still experiencing this issue in your application? If so, could you reproduce it in a JSBin such that we can test and debug it?

I see this problem when I use the ECMAScript 6 keyword "class" instead of the info objected passed in Polymer(info) function.
For example this:

addEventListener('WebComponentsReady', function () { 
class UserView extends Polymer.Element {
      static get is() {return 'user-view'}
     ready(){
      var grid =  this.$.grid;
    }

    customElements.define(UserView.is, UserView);
  }
}

will give this.$.grid undefined

@vasstavr You need to call super.ready(): http://jsbin.com/cefiyuqixu/edit?html,console,output For more info see #4529 and #4412

@TimvdLippe Thanks!!!

Closing per https://github.com/Polymer/polymer/issues/4175#issuecomment-320149642 We can reopen and investigate once we have a runnable JSBin

Was this page helpful?
0 / 5 - 0 ratings