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

Set a property with an array in a component will hang up everything #12644

Closed
nightire opened this issue Nov 25, 2015 · 7 comments
Closed

Set a property with an array in a component will hang up everything #12644

nightire opened this issue Nov 25, 2015 · 7 comments

Comments

@nightire
Copy link
Contributor

I've encounter a weird problem, I try to reproduce it with ember-twiddle but let me explain it first.

In a component's didRender hook, I need to calculate some DOM related data and expose it to the nested components, so I did something like below:

export default Ember.Component.extend({
  didRender() {
    let clientRect = this.element.getBoundingClientRect();
    let thresholdX = clientRect.right - 300;
    let thresholdY = clientRect.height * 0.75;

    // this will cause the problem
    // this.set('threshold', [thresholdX, thresholdY]);

    // this will work
    this.setProperties({ thresholdX, thresholdY });
  }
});

As commented above, set with an array will repeatedly throw deprecations crazily:

2015-11-25 18 37 44

I try to use ember-twiddle to reproduce it, but since it will hang the browser up, so I can't save it to share.

Ember v2.2.0

@nightire
Copy link
Contributor Author

BTW, I often see some deprecations to tell me not to modify property during didInsertElement or didUpdate hook, but I can't find anything did these modifications in those two hooks. For example the bug I mentioned above is to set a property in didRender hook, but it also warning me not to do this in didUpdate, that's making me crazy.

Components often need DOM calculations and depends on itself is actually rendered, if some property needs to be re-computed with its DOM changes (like height/width, position etc.), why can't do these in didRender hook? I might misunderstand or ignore something important, hope someone help me to clear these confusions.

@ptgamr
Copy link
Contributor

ptgamr commented Nov 25, 2015

Setting an array to a property shouldn't be a problem at all. Maybe you have observer somewhere, which also modifying the threshold property. Could you post the full code to here?

@nightire
Copy link
Contributor Author

@ptgamr No, I can confirm there's only one place to set threshold property, because I re-produce this demo on ember-twiddle and I only write didRender method like I mentioned above.

@ptgamr
Copy link
Contributor

ptgamr commented Nov 25, 2015

Ok I see :) I mangage to put a twiddle here: https://ember-twiddle.com/e916bd0c7d9ca46198f8

Setting the property on didRender & access that property on the template will make an infinite call to didRender.

For example: on didRender --> you update the property --> then the view updated --> didRender hook again....

@nightire
Copy link
Contributor Author

@ptgamr I understand your explanation, I actually thinking in this way at first, but later I change the set part to this:

this.setProperties({ thresholdX, thresholdY });

and the problem is gone...

why this works? this still set property(ies), instead of set one property with an array, I set two properties. It doesn't make any sense.

@nightire
Copy link
Contributor Author

@ptgamr with your inspiration, I made some test:

// instead of setProperties
// this.setProperties({ thresholdX, thresholdY }); 

// set them individually
this.set('thresholdX', thresholdX);
this.set('thresholdY', thresholdY);

this works fine, but if you change thresholdX or thresholdY to an array (even only contain one element):

// set them as an array
this.set('thresholdX', [thresholdX]);
this.set('thresholdY', [thresholdY]);

infinite call again...now I'm pretty sure Array is not allowed here, but I currently busy to finish the project so can't tracking the code execution flow, hope someone can take a look on this.

@rlivsey
Copy link
Contributor

rlivsey commented Nov 25, 2015

I'm guessing this is because if you set a property to the same as its current value it doesn't trigger change notifications.

When you set it to an array, [1] != [1] even though the contents are the same, so that triggers change notifications, which causes a re-render, which sets the value, which… and ends up in an infinite loop.

With primitives, this won't happen because it'll notice it's the same as before and so doesn't end up re-rendering the 2nd time.

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

3 participants