Skip to content
This repository has been archived by the owner on May 29, 2019. It is now read-only.

Correct documentation of dom-repeat.render(); add docs for notifySplices #1439

Closed
arthurevans opened this issue Nov 19, 2015 · 3 comments
Closed
Assignees
Milestone

Comments

@arthurevans
Copy link

From @wuyuanyi135 on November 19, 2015 4:47

I was trying to mutate a items array of a dom-repeat with javascript and see if the template will update after the change.

This is my test code, and I host it on c9 on Nov 19, 2015. Hope this helps.

<!DOCTYPE html>

<link rel="import" href="../polymer/polymer.html" />

<dom-module id="file-list">
    <template>
        Your files:
        <table>
            <template id="table_template" is="dom-repeat" items="{{fileItems}}">
                <tr>
                    <td>{{index}}</td>
                    <td>{{item.fileName}}</td>
                    <td>{{item.mimeType}}</td>
                </tr>
            </template>

        </table>
        <input type="button" value="Add one!" on-click="buttonClicked" />
    </template>

    <script>
        Polymer({
            is: "file-list",

            properties: {
                fileItems: {
                    value: [{
                        type: Array,
                        fileName: "filename 1",
                        mimeType: "mime 1"
                    }, {
                        fileName: "filename 2",
                        mimeType: "mime 2"
                    }],
                    notify: true
                }
            },

            buttonClicked: function() {
                //this.fileItems.push({fileName:"filename x",mimeType:"mimeType x"});
                //this.$.table_template.render();
                this.push("fileItems",{fileName:"filename x",mimeType:"mimeType x"});
            }
        });
    </script>
</dom-module>

The documentation page indicates that I need to use polymer function this.push("fileItems",object) rather than fileItems.push(object), otherwise I need manually call this.$.table_template.render() to update the template.

What happened is, when I append an object to fileItems array, the render() throws an exception

Uncaught TypeError: Cannot read property '0' of undefined
Polymer.Collection._parseKey @ polymer.html:3900
Polymer.Collection.getItem @ polymer.html:3919
Polymer._stampInstance @ polymer.html:4328
Polymer._insertInstance @ polymer.html:4338
Polymer._applyFullRefresh @ polymer.html:4201
Polymer._render @ polymer.html:4134
Debouncer.complete @ polymer.html:1231
Polymer.Base.extend.flush @ polymer-mini.html:1152
Polymer.Templatizer._flushTemplates @ polymer.html:3634
Polymer.render @ polymer.html:4129

I roughly traced the problem, and find that in function getKey in line 3883 of polymer.html, key = this.omap.get(item); was executed. But this.omap only contains 2 elements (initial value). Therefore, the new appended elements cause key to be undefined and then lead to the exception.

getKey: function (item) {
    var key;
    if (item && typeof item == 'object') {
        key = this.omap.get(item);
    } else {
        key = this.pmap[item];
    }
    if (key != undefined) {
        return '#' + key;
    }
}

Did i use the proper way to invoke render()? How can I update this.omap?

Copied from original issue: Polymer/polymer#3022

@arthurevans arthurevans self-assigned this Nov 19, 2015
@arthurevans
Copy link
Author

Maybe related to Polymer/polymer#3018?

@kevinpschaaf I would expect this to work, but apparently it doesn't. In v.1.2.3, it throws as described in #3018. In v1.1.5, it doesn't throw, but the wrong data is displayed.

@arthurevans
Copy link
Author

From @kevinpschaaf on November 19, 2015 17:20

This documentation is in error:

You can use the render method to force a dom-repeat to update (for example, if you’re using a third-party library that mutates the array).

Calling the render method is useful for:

  • Forcing a synchronous render of changes that have occurred to the data (this is normally batched and rendered asynchronously)
  • Re-running the filter/sort functions on the view due to changes to the filter/sort criteria

The description of any changes to the array that occurred without use of the provided array mutation API must be provided using the public notifySplices method. render() does not provide a substitute for this.

@arthurevans arthurevans changed the title calling render() of dom-repeat after mutate the items array causes "Uncaught TypeError: Cannot read property '0' of undefined" Correct documentation of dom-repeat.render(); add docs for notifySplices Nov 19, 2015
@wuyuanyi135
Copy link

👍

@arthurevans arthurevans added this to the Q4S5 milestone Nov 19, 2015
@arthurevans arthurevans modified the milestones: 2016Q1S2, Q4S5 Jan 15, 2016
kaycebasques added a commit that referenced this issue Feb 3, 2016
document notifySplices and fix render; fixes #1439
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants