Polymer: detecting an object property change from the parent component

1.1k views Asked by At

I have a component that loads an object from Firebase using firebase-document. Then that object is passed to a child component. When I change the object in the child component, the change is not detected in the parent, so the object is not updated in Firebase.

Here is the main component:

<dom-module id="some-component">

  <template>

    <firebase-document path="/projects/[[project_id]]" data="{{project}}"></firebase-document>

    <some-child project="{{project}}"></some-child>

  </template>

  <script>
    Polymer({
      is: 'some-component',
      properties: {
        project: {type: Object, notify: true, observer: "projectChanged"}
      },
      projectChanged: function() {
        console.log("we've detected some changes!");
      }
    });
  </script>

</dom-module>

And here is the child component:

<dom-module id="some-child">

  <template>

    <a on-tap="changeProject">Let's change some property on our project!</a>

  </template>

  <script>
    Polymer({
      is: 'some-child',
      properties: {
        project: {type: Object, notify: true}
      },
      changeProject: function() {
        this.project.name = "A new name"; // this never propagates back to the parent component
      }
    });
  </script>

</dom-module>

The expected behavior is that when I click on the link, the object's property would change, it would be detected by the parent, and there would be a console.log. However it doesn't seem to happen.

Update with the solution

Using this.set() in the child component does the trick:

this.set("project.name", "A new name")
1

There are 1 answers

1
Arfost On BEST ANSWER

I think your issue here, is from the observer.

A simple observer like this only watch the reference of the object itself. You can use a deep observer instead like this

properties: {
    project: {type: Object, notify: true}
},
observers:[
    'projectChanged(project.name)'
],

or for a more properties generic version

properties: {
    project: {type: Object, notify: true}
},
observers:[
    'projectChanged(project.*)'
],

and it should work like this. Here is the link to the full documentation on the subject. https://www.polymer-project.org/1.0/docs/devguide/observers#observing-path-changes

To be perfect you can also change the classic way of setting the value by the polymer way, it ensure better detection by the framework, remplacing

this.project.name = "A new name";

by

this.set("project.name", "A new name")

It will help on complexe binding case, or heavy objects it seems.