Polymer and Firebase: changing the path of <firebase-query> dynamically

511 Views Asked by At

I have a in a component, which fetches some data. The path is dynamic, as it has a binding inside it.

I then have some links that change the path dynamically. I would expect the list of data to update accordingly.

when I first load the page, it works all fine, but whenever I click on a link to update the path (and therefore to fetch new data), it returns nothing.

I checked what was going on with an observer, and it looks like whenever I update the path the data is updated twice: first it returns the actual data I would expect, and then it returns an empty array.

Here is the component:

<dom-module id="test-one">

  <template>

    <firebase-query app-name="main" path="/templates/[[template]]" data="{{items}}"></firebase-query>

    <a on-tap="changeTemplate" data-template="template1">Template 1</a><br />
    <a on-tap="changeTemplate" data-template="template2">Template 2</a><br />

    <p>Current template is [[template]]</p>

    <template is="dom-repeat" items="{{items}}" as="item">
      [[item.ref]] - [[item.description]]<br />
    </template>

  </template>

  <script>
    Polymer({
      is: 'test-one',
      properties: {
        items: {type: Array, observer: "dataChanged"},
        template: {type: String, value: "template1"},
      },
      dataChanged: function(newData, oldData) {
        console.log(newData);
      },
      changeTemplate: function(e) {
        elm = e.currentTarget;
        template = elm.getAttribute("data-template");
        console.log("link has been clicked, we're changing to "+template);
        this.set("template", template);
      }
    });
  </script>

</dom-module>

This is what the console shows when I click on one of the links:

enter image description here

There seems to be some asynchronious sorcery going on - any idea on how to solve this?

2

There are 2 best solutions below

0
On BEST ANSWER

This is effectively a bug in firebase-query, fixed with this pull request: https://github.com/firebase/polymerfire/pull/167.

It has already been reported here: https://github.com/firebase/polymerfire/issues/100

2
On

Looks like this is a bug in Polymerfire. For now making the following changes to your local copy of firebase-database-behavior.html will fix the problem, seemingly without artifacts, however this really requires a bug report. I will get to filling a bug report as soon as I get a chance, they tend to have a lot of time consuming back and forth :(

Simply comment out line 86 in firebase-database-behavior.html. The new __pathChanged function should look as so.

__pathChanged: function(path, oldPath) {
  if (oldPath != null && !this.disabled && this.__pathReady(path)) {
    this.syncToMemory(function() {
      // this.data = this.zeroValue;
    });
  }
},

What's Going On

When the path changes there is code written to zero out the old value, and this code lives in firebase-databse-behavior.html, which firebase-query inherits. This makes sense, however firebase-query already zeros out the data upon __queryChanged at line 279 in firebase-query.html.

__queryChanged: function(query, oldQuery) {
  if (oldQuery) {
    oldQuery.off('child_added', this.__onFirebaseChildAdded, this);
    oldQuery.off('child_removed', this.__onFirebaseChildRemoved, this);
    oldQuery.off('child_changed', this.__onFirebaseChildChanged, this);
    oldQuery.off('child_moved', this.__onFirebaseChildMoved, this);

    this.syncToMemory(function() {
      this.set('data', this.zeroValue);
    });
  }

  if (query) {
    query.on('child_added', this.__onFirebaseChildAdded, this.__onError, this);
    query.on('child_removed', this.__onFirebaseChildRemoved, this.__onError, this);
    query.on('child_changed', this.__onFirebaseChildChanged, this.__onError, this);
    query.on('child_moved', this.__onFirebaseChildMoved, this.__onError, this);
  }
},

Changes to the path are first observed by firebase-query by __computeQuery at line 23 in firebase-query.html. __queryChanged is then triggered zeroing out the old data and sets up firebase event handlers to observe changes to the firebase database. Subsequently, __pathChanged in firebase-database-behavior.html is called which again zeros out the data, but after the new data has already been written by the firebase event handlers.