Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom elements seem to cache data after being deleted and re-added #159

Closed
anniesullie opened this issue May 23, 2013 · 8 comments
Closed

Comments

@anniesullie
Copy link

The context for this is crbug.com/242701

I made a jsfiddle to reduce the problem a bit:
http://jsfiddle.net/jqUs7/

The fiddle has a my-element custom element, with this.foo = {}. Click on the element and it sets this.foo.bar = 'hello!'. Then click the button, the element is deleted, a new one is created using document.createElement, and appended to the div. The new element renders {{foo.bar}} as 'hello!' when it should be undefined.

@sorvell
Copy link
Contributor

sorvell commented May 23, 2013

The problem here is that the foo property has been set to a static object
that will be shared by all instances.

Instead, when a property needs to be a non-shared object value, the proper
way to initialize it is in the ready method:

ready: function() {
  this.foo = {};
  // arrays too
  this.list = [];
}

@sjmiles
Copy link
Contributor

sjmiles commented May 23, 2013

For the language lawyers, static is a tricky term, more simply the foo object has been set on the element's prototype. By definition, the prototype is shared by all the instances.

For posterity:

The tricky part is that, normally, setting a property in an instance creates that property on the instance. If I put zot: 3 in my prototype, then do this.zot = 5; the 5 is not shared across instances, so why is it different when I set this.foo.bar = 5?

The answer is that when you set a property like foo.bar you are not setting a property on the element instance, but on foo. As Steve mentioned, this same effect occurs if you manipulate an array that is declared on a prototype.

Fwiw, I believe that this particular footgun is why ES6 disallows (non-function) properties in Class definitions.

@anniesullie
Copy link
Author

Thanks, that helps a lot! I've refactored my code to avoid this problem.

Note that there are some examples with similar code in the docs:
http://polymer-project.appspot.com/polymer.html

Polymer.register(this, {
  person: {
    name: "Scott",
    nameColor: "orange"
  }
});

So it kind of looks like this is the "right way" to initialize a property.

@morethanreal
Copy link
Contributor

I think there's a subtle point here that the element registration is
evaluated once, so only one instance of the object used in property
initialization is ever created, vs. this.ready() is evaluated every time
you create an element instance. Does this merit a note in the docs?

On Thu, May 23, 2013 at 12:40 PM, anniesullie [email protected]:

Thanks, that helps a lot! I've refactored my code to avoid this problem.

Note that there are some examples with similar code in the docs:
http://polymer-project.appspot.com/polymer.html

Polymer.register(this, {
person: {
name: "Scott",
nameColor: "orange"
}
});

So it kind of looks like this is the "right way" to initialize a property.


Reply to this email directly or view it on GitHubhttps://github.com//issues/159#issuecomment-18366911
.

@sjmiles
Copy link
Contributor

sjmiles commented May 23, 2013

The key concept here is that the thing you are registering is a prototype. I can see how this is not clear from the register call itself and we should enhance clarity here.

Polymer.register is a sugaring around document.register, which has a signature like document.register(name, dictionary), where dictionary is expected to have prototype property. We sugared away most of that so you pass in the prototype directly which has probably made this a bit foggier.

Most of these issues flow from the nature of prototype, which is strictly speaking out of scope for Polymer to explain. I admit that prototype can be tricky, and the more documentation the better, but it's good to be clear regarding concepts we are introducing vs concepts are just part of the platform.

@sjmiles
Copy link
Contributor

sjmiles commented May 23, 2013

Note that there are some examples with similar code in the docs:

You are right, that's extremely bad. :)

@anniesullie
Copy link
Author

Thanks for all the explanations!

For me, changing the "person" example in the documentation and including the note about registration (once vs every instance) would be good improvements to the docs. I agree a really in-depth explanation of what's happening here is definitely out of scope for the current Polymer docs.

@ebidel
Copy link
Contributor

ebidel commented May 24, 2013

Fixed up the docs and made a note for object initialization:
Polymer/old-docs-site@db50065

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants