polymerfire icon indicating copy to clipboard operation
polymerfire copied to clipboard

Need to manually / force notify change to dom-repeat when firebase query data are not directly exposed

Open stillgbx opened this issue 8 years ago • 2 comments

Description

I don't know if I'm doing it wrong or if it's really an issue (polymerfire ? polymer ?).

In my app, I have to display some parts of a Firebase query results (I don't have implemented Elasticsearch yet). For that, I do not directly expose the query data in order to be able to "filter" them. I populate "filtered" data with "raw" data which interests me.

All seems to be ok, except when I update values in the Firebase console. dom-repeat does not receive change notifications, however "raw" and "filtered" data are ok and well reflect what is stored in the database.

The only workaround I've found is to manually/force notify change on "filtered" data with something like: this.set(path, this.get(path));

Code exemple (sorry no live demo)

<!-- Polymer elements -->
<link rel="import" href="../bower_components/polymer/polymer.html">
<!-- Firebase elements -->
<link rel="import" href="../bower_components/polymerfire/firebase-app.html">
<link rel="import" href="../bower_components/polymerfire/firebase-query.html">

<dom-module id="gbx-test">
  <template>

    <firebase-app api-key="YOUR_FIREBASE_API_KEY" auth-domain="YOUR_FIREBASE_AUTH_DOMAIN" database-url="YOUR_FIREBASE_DATABASE_URL" name="test" app="{{firebaseApp}}"></firebase-app>
    <firebase-query data="{{_data}}" app="{{firebaseApp}}" path="/data" app-name="test"></firebase-query>

    <template is="dom-repeat" items="{{_computedData}}">
      <div>
        {{item.name}}
      </div>
    </template>

  </template>

  <script>

    Polymer({
      is: "gbx-test",

      properties: {

        _data: {
          type: Array
        },

        _computedData: {
          type: Array,
          value: function(){
            return [];
          },
          notify: true
        }

      },

      observers: [
        "_onDataItemsChanged(_data.splices)",
        "_onDataItemsChanged2(_data.*)"
      ],

      _onDataItemsChanged: function(changeRecord){
        if(changeRecord){
          // for the example we don't filter anything
          this._computedData = changeRecord.indexSplices[0].object;
        }
      },

     // here is the workaround
      _onDataItemsChanged2: function(changeRecord){
        if(changeRecord.path.split(".").length > 2){
          var path = changeRecord.path.replace("_data", "_computedData");
          this.set(path, this.get(path));
          // or
          // this.set(changeRecord.path.replace("_data", "_computedData"), changeRecord.value);
        }
      }

    });

  </script>
</dom-module>

Steps to reproduce

  1. Create a test database in your Firebase console
  2. Import the test data test-data.json.txt
  3. Create a component with the above code example
  4. Replace YOUR_FIREBASE... with those of your Firebase test database
  5. Play

Browsers Affected

  • [x] Chrome
  • [x] Firefox
  • [ ] ... and probably all others

Additional notes

Content of test-data.json.txt

{
  "data" : [ null, {
    "name" : "original data 1"
  }, {
    "name" : "original data 2"
  } ]
}

stillgbx avatar Aug 23 '16 16:08 stillgbx

I (think?) this is expected behavior for a dom-repeatwith a filter, at least I've run into this both with Firebase and non-Firebase apps. @cdata @robdodson is it expected that the render will have to be manually triggered?

mbleigh avatar Sep 09 '16 07:09 mbleigh

I can't remember the change record api off the top of my head unfortunately. Polymer's data binding system works by object reference, so if any of the object references are the same after your change, it won't trigger the bindings to run. (BTW we're fixing this soon). Calling this.set should poke the data binding system to tell it to look at the new objects so your workaround may be the correct solution if there's the possibility that the object references remain the same but their inner contents have changed

robdodson avatar Sep 09 '16 15:09 robdodson