Polymer 1.0: Does <iron-meta> support binding to dynamic variables? - polymer

I can get my <iron-meta> instance to work properly when using a static value. But when I bind the value to a dynamic variable (using {{}}) it <iron-meta> no longer behaves as expected.
Does <iron-meta> support binding its value to dynamic variables?
<iron-meta id="meta" key="info" value="foo/bar"></iron-meta> // works
<iron-meta id="meta" key="info" value="{{str}}"></iron-meta> // fails
Previous work
This question is a refinement of this question in order to clarify that the ONLY thing causing the problem is the change from a static string value to a dynamic string value binding. I was getting a lot of other suggesting that had nothing to do with the change from static to dynamic so I thought it might be best to rewrite the question to clarify that. But the entire code context is contained in the links there if that would help.
Alternative solutions
There has been some recent chatter about using <iron-localstorage>. Perhaps that is the best way to go for dynamic binding essentially creating global variables?

Yes, <iron-meta> does support binding to variables, but perhaps not in the way you think.
Example: http://plnkr.co/edit/QdNepDrg9b3eCTWF6oRO?p=preview
I looked through your code here, here, and here but I'm not entirely clear what your expectations are. Hopefully my attached repro might shed some light. I see you have declaratively bound <iron-meta id="meta" key="route" xvalue="foo-bar" value="{{route}}"></iron-meta> which is fine - when route changes, iron-meta's key="route" will update accordingly.
However, be aware that in Polymer 1.0, <iron-meta> is in essence a one-way bind from parent to child in the sense that you set a meta key value dynamically by binding to a property; but to get that value, you'll have to get it imperatively via iron-meta's byKey() method.
<iron-meta> is just a simple monostate pattern implementation without an in-built path notification mechanism. What this means is value changes do not propagate upwards. Therefore, doing something like
<!-- this does not work like the way you think -->
<iron-meta id="meta" key="foo" value="{{bar}}">
in order to get the value of foo, or listen to changes to foo, does not work. This behaves more like a setter, where you set the value of foo based on your data-bound property bar.
From what I gather, it seems that you're trying to implement some sort of global variable functionality. A monostate implementation used to work in Polymer 0.5, but not in 1.0. Unfortunately, until Google endorses a "best-practice" pattern for this, suggestions till-date seems a bit speculative to me. You might find this (Polymer 1.0 Global Variables) helpful.

I have had success using <iron-signals> to communicate global information. I know there is a warning in the <iron-signals> documentation that discourages its use for related elements, but when broadcasting a shared resource it seems just the thing. For example:
// source element
var db = SomeDB.init();
this.fire('iron-signal', { name: 'database', data: db });
<-- sink element -->
<iron-signals on-iron-signal-database="dbChange"></iron-signals>
class SinkElement {
dbChange(e, detail) {
this.db = detail;
this.db.getSomeData();
}
}

Related

LitElement lifecycle: before first render

Is there a way to execute a method exactly after the component has its properties available but before the first render?
I mean something between the class contructor() and firstUpdated().
It sounds trivial, maybe in fact I'm missing something trivial..
The element's constructor is called when the element is created, either through the HTML parser, or for example through document.createElement
The next callback is connectedCallback which is called when the DOM node is connected to the document. At this point, you have access to the element's light DOM. Make sure to call super.connectedCallback() before doing your own work, as the LitElement instance has some work to do here.
The next callback is shouldUpdate, which is an optional predicate that informs whether or not LitElement should run its render cycle. Useful if for example, you have a single observed data property and destructure deep properties of it in render. I've found that it's best to treat this one as a predicate, and not to add all sorts of lifecycle logic inside.
After that, update and render are called, then updated and firstUpdated. It's generally considered bad practice to perform side effects in render, and the occasions that you really need to override update are rare.
In your case, it sounds very much like you should do your work in connectedCallback, unless you are relying on LitElement's rendered shadow DOM, in which case, you might consider running your code in firstUpdated, then calling this.requestUpdate() to force a second update (or changing some observed property in firstUpdated)
More info: https://lit-element.polymer-project.org/guide/lifecycle

Use a global variable in Polymer dom-if

I am creating a custom module for Polymer. I need to create a global variable that can be accessed when defining a template. Something like:
<template is="dom-if" if="[[_check(myGlobalVar.foo)]]">
The global variable should also be directly accessible from inside the module (see _anotherFunction) . The JS file looks like:
Polymer({
is: 'my-module',
_check(f) {
return f == 'foobar'
},
_anotherFunction() {
console.log(myGlobalVar)
}
})
In addition, myGlobalVar should be accessible from other modules in other files. What's the best way to create it?
You can achieve that in two ways.
Have a component that can hold all the global variables and gives the same instance of its data where ever it is used. You can find the better explanation using link along with working sample
If you have lot of data that needs to be accessible globally then the best option would be using store with polymer-redux.
There is a specific Polymer element for this.
iron-meta is a generic element you can use for sharing information
across the DOM tree.
https://www.webcomponents.org/element/#polymer/iron-meta
The element fires value-changed if a value has been changed, so you probably need to set up values for it.
We don't use it in our company however, but just storing the value in memory, and then send an event whenever we set the value. Also adding a listener for every element that needs to listen to updates.

PolymerElements API reference?

Where can I find a full API reference for PolymerElements?
For example, the description for PaperDialogBehavior says
Use the dialog-dismiss and dialog-confirm attributes on interactive controls to close the dialog. If the user dismisses the dialog with dialog-confirm, the closingReason will update to include confirmed: true.
But I can't find any further information anywhere about what closingReason actually is (a property? a parameter passed to some callback?) and how it "includes" confirmed: true.
Instead of wasting time on guessing how to do every single little thing when using Polymer, it would be nice to have an actual API reference. Is there one?
There isn't any further information. Documentation isn't well written and you have to find many things on your own. Just remember that everything in Polymer is about properties. So closingReson is property that you can access on paper-dialog (or any other elements using paperDialogBehavior).
This property contains object {confirmed: true|false}
Truly said, behaviors has extremely badly written documentations. It is very confusing. For example:
modal: boolean = false
If modal is true, this implies no-cancel-on-outside-click, no-cancel-on-esc-key and with-backdrop.
but none of those properties are specified in paperDialogBehavior, because it is inherited from iron-overlay-behavior. And these inheritences are not documented (mostly).

knockout tutorials - "this" property binding?

These are from the knockoutjs.com tutorials.
Can anyone explain what the "this" at the end of the fullName property does? Please mention the JS principle at work here so that I may read about further, thanks!
Why does the totalSurcharge property not need the "this" at the end?
The second argument to a ko.computed sets the value of this when the function to determine the computed's value (the first arg) is executed. In the fullName case, the function uses this.firstName and this.lastName. So, whenever it is called we want to make sure that this is indeed our viewmodel.
In the second case, a variable called self was created that points to the appropriate value of this. Then, self is used inside the computed's function rather than using this (which is dynamic). In the second case, self could have been put as the second argument and then this could have been used inside the function.
This is really a matter of style. In my opinion, the use of a variable like self has fallen out of style these days. In the end, it comes down to personal preference.
Here is another answer that discusses this in KO as well: Difference between knockout View Models declared as object literals vs functions
Good tutorial on this in JavaScript here: https://derickbailey.com/email-courses/masteringthis/

Has there been any known improvements of Class <--> Json Serialization?

Dart has a known error where a class you create with public variables can not be passed into native JSON template calls. I was not sure if there has been any improved headway on this.
Example;
class Test{
String a;
int b;
}
would be nice to translate into:
{"a":"","b":0}
It seems when looking around the internet and forums for dart, this was an issue, and with a language that works so closely with Javascript, a terribly large oversight. I havent seen anything yet, though it seems you might be able to scrape a the public variables if you are using mirrors, which is seemingly time intensive.
Here is what a sample is that I am working on.
class UserGroup{
String a;
int b;
UserGroup.fromMap(Map m){ ... }
}
I receive from a Service call, a map which is cast to a UserGroup.
This will then produce a List which are binded and passed into a sub WebComponent which will access a Map. Something like this.
<service-call result="{{rowData}}"></service-call>
<grid-creator rows="{{rowData}}"></grid-creator>
and inside of grid creator:
<dom-module id="grid-creator>
<template>
<div>
<template is="dom-repeat" for="{{rows}}" as="row">
<div id="{{row.id}}">{{row.name}}</div>
</template>
</div>
</template>
</dom-module>
The issue had has is that the grid-creator is dynamic, accepting a row of maps and parsing accordingly. Even if I were to say List<UserGroup> rows it doesnt understand it as row and will throw an error like:
type 'UserGroup' is not a subtype of type 'Map' of 'row'
That means that Dart classes nativly cannot interact with template repeaters at all, unless the class itself is a subtype of map. which wouldnt make sense to me.
That being said, a lot of the notes are from September 2015 and prior. I was curious where this has progressed.
You could say: Well, why not just have a toJson method which turns a map, then parse and intercept the class and convert it before it it hits the template.
I mean, i guess that could be a thing if i do an observer on the rowData and then have a second variable which is populated and subsequently refresh the grid-creator but that that isnt really the point. It sort of removes the Object from being passed around and at that point, I should just remove the class component and just use maps. If im just using maps, then why the heck would i use dart? /endrant
Anyways, has there been improvements in this area?
One of the threads i was reading about serialization: https://github.com/dart-lang/sdk/issues/16630
Edit: I was trying to look into the concept of having the class UserGroup extend JsProxy, but i dont think that would resolve the issue i was having