Polymer: Determining when properties have loaded? - polymer

I know the attached function doesn't guarantee that properties will be loaded.
Right now, I've been using a computed Function that depends on properties but it's very clunky.
I've also used async but I find it to be inconsistent and arbitrary (just picking a random time to delay by).
I can't find anything about the correct way to deal with this problem.

You can use observers.
for example you
properties:{
someproperty:{type:Number,observer:'change'}
},
change:function(){
//this function called when the property changes.
}
for more information look at https://www.polymer-project.org/1.0/docs/devguide/properties.html

In addition to Alon's answer: if you want to observe several properties, then you can use something like this:
properties:{
someproperty1:{
type: Number,
}
someProperty2:{
type: Number,
}
},
observers: ['change(someproperty1, someproperty2)'],
change:function(property1, property2){
//this function called when the property changes.
},
Note, when using single observers, they will fire in the order they are set. So if someproperty1 and someproperty2 had specific observers binded to them, then the method that someproperty1 had will be executed first.
To read more about observers, read here:
https://www.polymer-project.org/1.0/docs/devguide/observers#multi-property-observers

Related

How to know which rules were applied during autoformatting using PhpStorm?

I am trying to figure what rules PhpStorm is using in my current file during autoformatting via "Reformat Code" so I can tweak it better. Is there way to view the rules that were applied?
A more concrete example:
I have a file with this code:
public function rules(): array {
return array_merge(parent::rules(), [
['foo', 'bar'],
];
}
that is converted into:
public function rules(): array {
return array_merge(parent::rules(),
[
['foo', 'bar'],
]
]
}
but I don't know which rule I have to tweak in order to not apply that change. I also want to be able to tell in other cases which ruleset caused which change during autoformat.
Is that possible and if so how?
In general, you can check that by selecting a code block and then Help | Find Action | Adjust code style settings.
But, please be aware that it is not all that precise, it can and does miss things. In your particular case, try playing around with Function/constructor call arguments and Array initializer in Wrapping and Braces.

How to check the (initial) render state (not the update state) of a component in shadow DOM

Following the question I would like to ask about the appropriate way to check the initial render status of a component (not the update status) in shadow DOM. Is there any similar to document.readyState or a promise?
I have also tried to do:
getItems() {
this.updateComplete
.then(() => {
this.nodesLists = this.shadowRoot.querySelectorAll(".name");
})
.then(...)
}
which also failed.
Tia
await this.updateComplete (or this.updateComplete.then(...)) is the correct way to wait until the element has no pending render work before e.g. querying the state of the element's rendering, so your code should generally work as long as the element is connected to the document before running getItems.
Example: https://jsbin.com/jiquhez/edit?html,console,output
Note however, that if you await updateComplete before the element is connected and the element has no properties set that would trigger a render, then updateComplete currently resolves before the first render. This may be considered an unintended bug, filed at lit-element/#594.
Note you may also want to look into using the firstUpdated lifecycle method, depending on your use case. This is a method you can implement on your class to perform one-time work following the first update/render cycle for the element (useful for e.g. selecting static nodes that won't change based on rendering).
Example: https://jsbin.com/limikas/edit?html,console,output

How to use Polymer lifecycle hooks

I have a component that contains video. My component is nested in a dom-if and can disappear. When this happens the video (and it sound) keep playing.
Is there a way in which my component can detect that is has disappeared from the DOM? I have tried to use the 'detached' callback as described here: https://www.polymer-project.org/1.0/docs/devguide/registering-elements
Polymer({
is: 'my-component-with-video',
properties: {
// some properties
},
detached: function() {
console.log('Component detached');
// more code to stop video
},
but when my element is removed by the dom-if nothing happens, I don't see the console.log message. What am I doing wrong?
There are two scenarios possible here:
You want your element to be discarded and recreated fresh when the condition changes.
You want to keep it in the dom but freeze it.
In the first case you need to add the restamp attribute to the dom-if to make sure the template DOM is destroyed, not hidden. By default the dom-if stamps the template at first initialization and then hides it from the view if the condition becomes falsy.
In the second case, the suggestion given by Intervalia will not work, because the dom-if in "hide" mode does not detach anything from the DOM. Setting restamp attribute will make the detached callback run but then no point in pausing anything since the element will be discarded.
If you want to keep it in the DOM and freeze it's state you need to listen to dom-change event on the dom-if and run the .pause() accordingly.
No need for any workaround other than simply using your dom-if and rather than
<dom-if if="[[condietionBoolean]]">
<your-video-element id="giveanId"></your-video-element>
</dom-if>
write the if statement like below and so each time your condition changes, you check and make sure the video is paused if when you like. See below.
...
<dom-if if="[[_shouldShowVideo(conditionBoolean)]]">
<your-video-element id="giveanId"></your-video-element>
</dom-if>
...
Polymer({
is: 'my-component-with-video',
properties: {
conditionBoolean : {
type: Boolean,
},
},
_shouldShowVideo: function(conditionBoolean ) {
if (!conditionBoolean) this.$$(#yourVideoElementId).pause();
return conditionBoolean ;
}
});
In your detached function you need to get the Video Element and call .pause() on it.
You will probably also need to call .pause() when your condition changes that would cause the dom-if to remove the player.

Polymer callback as an attribute

Not so long ago I noticed that iron-ajax uses an attribut on-response="callbackFn" to execute once a response is received.
My question is simply how does this work?
I have a similar situation where I would like create a component that is able to take a callback as an attribute but I can't figure out how to do it.
Two things I noticed
When triggered the function is correctly bound to the Polymer element from which it came.
"callbackFn" is the name of a function. Not a polymer binding.
So I assumed iron-ajax must be doing some trickery in the background to bind the given function referenced by function name. When I looked at the source code though I don't see any handling of the 'on-response' attribute. none, zilch, nada. what gives?
I can see that there is a _boundedHandleResponse but that property does not seem to be bound to the on-response function at any point.
source
_boundedHandleResponse is a function which is value depends upon the _handleResponse function.
_boundHandleResponse: {
type: Function,
value: function () {
return this._handleResponse.bind(this);
}
}
So, if you check the _handleResponse function there is a 'response' event which is dispatched using the code :
this.fire('response', request, {
bubbles: this.bubbles,
composed: true
});
In polymer element we add event listeners using on-event annotations. For example on-tap, on-click. So, every time response is dispatched it will call the function defined as on on-response="callbackFn" which will call the "callbackFn" function.

Dom-Repeat Render: What is it actually do? Proper way to tell dom-repeat re-render its item?

I was fighting with a nested dom-repeat for the last 2 days.
I somewhat now know how to re-render when sub-properties changed.
But still don't understand the purpose of the render function.
I changed the data binded to a dom-repeat, and call the render, but nothing happens.
_renderDREmployees: function() {
this.employees[0].name="RENDERED"
// Why this doesn't work ?
this.$.drEmployees.render()
},
See here
http://plnkr.co/edit/Y0P5vNxg46t5fX7gJFxU?p=preview
Could somebody explain to me please?
If you could take a look of my example, to see if I do it the right away.
What could be other ways/proper way to re-render item inside a dom-repeat when the data that binded to it was changed outside.
Thank you
In order to mutate object properties in Polymer, you must use the object mutation methods in order for this changes to propagate inside your element.
Hence,
this.employees[0].name="RENDERED"
should be
this.set('employees.#0.name', 'RENDERED')
render only picks up observable changes such as those made with Polymer's array mutation methods.
Here is example where it works(I mean on name="RENDERED"): Plunk
Right way to do it is:
this.set('employees.0.name', "RENDERED set");
Docs Polymer array-binding