José Javier José Javier - 9 days ago 4
Dart Question

Databinding structured object does not show any change on my polymer element

I am migrating an application to Polymer 1 from 0.5 and using Dart. I was doing okay but now I am facing some data binding issues:

I have created a polymer element that programatically inserts on its Local DOM another polymer element giving the information of a contact. The second element will get the information from the constructor and show it on the interface via data binding.

Parent dart:

@PolymerRegister('test-app')
class TestApp extends PolymerElement {
TestApp.created() : super.created();

attached() {
super.attached();
async(() {
insertTile();
});
}

void insertTile() {
String contactJSON = '{"contactId":"1", "firstName":"Lex", "surname":"Luthor"}';
Contact contact = new Contact(JSON.decode(contactJSON));
ContactTile tile = new ContactTile(contact, this);
Polymer.dom(this.root).append(tile);
}
}


Parent html:

<dom-module id="test-app">
<style>
:host {
display: block;
}
</style>

<template>
</template>
</dom-module>


Children dart:

@PolymerRegister('contact-tile')
class ContactTile extends PolymerElement {
factory ContactTile(Contact contact, Element parent) {
ContactTile tile = new Element.tag('contact-tile');
tile.contact = contact;
return tile;
}

ContactTile.created() : super.created();

@property Contact contact;
}


Children html:

<dom-module id="contact-tile">
<style>
:host {
display: block;
}
</style>

<template>
<div>{{ contact.contactId }}</div>
<div>{{ contact.firstName }}</div>
<div>{{ contact.surname }}</div>
</template>
</dom-module>


Contact class:

class Contact {
String contactId;
String firstName;
String surname;

Contact(Map map) {
contactId = map['contactId'];
firstName = map['firstName'];
surname = map['surname'];
}
}


For some reason the data binding does not show any of the attributes of the contact on the web interface after the contact is updated on the constructor. Is anybody able to help me with this? I have done this many times on Polymer 0.5 but on Polymer 1 this does not work.

Thank you very much.

==============================

SOLUTION

The problem was related to the notification not being raised on the constructor of ContactTile. I could fix this by modifying the contact using the "set" function which updates the property and notifies.

@PolymerRegister('contact-tile')
class ContactTile extends PolymerElement {
factory ContactTile(Contact contact, Element parent) {
ContactTile tile = new Element.tag('contact-tile');
// tile.contact = contact;
tile.set("contact", contact);
return tile;
}

ContactTile.created() : super.created();

@property
Contact contact;
}


Also for accessing to the object attributes, I had to make the class to extend JsProxy and add @property to every attribute (or @reflectable for methods).

import 'package:polymer/polymer.dart';

class Contact extends JsProxy {
@property
String contactId;
@property
String firstName;
@property
String surname;

Contact(Map map) {
contactId = map['contactId'];
firstName = map['firstName'];
surname = map['surname'];
}
}

Answer

Since the Contact class isn't a full custom element, should it inherit from JsProxy and have annotations of the properties. This will make the properties accessible in html. Shown below.

class Contact extends JsProxy {
  @property String contactId;
  @property String firstName;
  @property String surname;    

  Contact(Map map) {
    contactId = map['contactId'];
    firstName = map['firstName'];
    surname = map['surname'];
  }
}
Comments