Search code examples
ractivejs

ractive array is changing, but not computed value


I use an array of objects as data for my ractive component (received from a PouchDB) which needs filtering inside ractive for the proper output. But anything I tried - even if the data - referred to as "docs" is changed correctly, the filtered aka computed values stay the same.

I tried with method:

 new Ractive({
        el: '#container',
        template: Listing,
        magic: true,
        modifyArrays: true,
        data: {docs},
        computed: {
            List: function(){
                let tempList = [];
                for(var i = 0; i < docs.length; i++) {
                    if (docs[i].specificValue == otherValue)  {
                        let newValue = docs[i];
                        tempList.push(newValue);
                    }
                }
                return tempList;
                }
            }
    });

with a helper object

Ractive.defaults.data.helper = function () {
        for (var i = 0; i < docs.length; i++) {
            if (docs[i].specificValue == otherValue) {
                return docs[i].whatever ;
            }
        }
    }
 new Ractive({
        el: '#container',
        template: '{{helper()}}',
        magic: true,
        modifyArrays: true,
        data: {List: docs}
    });

and a data function as described in Ractive computed property

But nothing worked the way expected. When I use docs directly the binding works as expected.

PS: the code may look a bit awkward because I just copied and simplified.


Solution

  • Ractive relies on the presence of this.get() to know which data a computation depends upon.

    With this, the area property can be treated like any other. It will update reactively (because the calls to ractive.get() tell Ractive that it should be recomputed when width or height change), so you can do...

    In your example, you are accessing docs directly. Ractive will not be aware that docs is a dependency of List.

    Here's a comparative example of a list using this.get() vs one that does not:

    var arr = [0, 1, 2, 3];
    
    new Ractive({
      el: 'body',
      template: `
      	<div>Working: {{# workingList }}{{.}}{{/}}</div>
      	<div>Not working: {{# nonWorkingList }}{{.}}{{/}}</div>
      `,
      magic: true,
      modifyArrays: true,
      data: {
        list: arr
      },
      computed: {
        workingList() {
          return this.get('list').map(n => `#${n}`);
        },
        nonWorkingList() {
          return arr.map(n => `#${n}`)
        }
      }
    });
    
    setInterval(() => {
      arr.push(arr.length);
    }, 1000);
    <script src="https://unpkg.com/ractive@0.8.9/ractive.min.js"></script>