[Hint] Observing changes in JS objects using ObjectObserver

74 views
Skip to first unread message

thegarre...@gmail.com

unread,
Feb 16, 2015, 10:24:44 AM2/16/15
to polym...@googlegroups.com
I didn't see this pattern in the list recently, so I though I would share the best way I've found to the old "AJAX-on-form-change" listener. This has the benefit of using the committedValue attribute so that the AJAX call is only called when the focus is blurred. This can also be helpful if you can't/don't want to create an observe: list in your Polymer declaration. I've included a CRUD custom element that is very similar to what Baasic created (but cleaned up a bit), but you should be able to get the gist of what is going on: 

1) Perform a GET call to obtain the facility data.
2) When handling the response, send a committedValue object to an ObjectObserver function along with the CRUD call object. We do this when we handle the response as opposed to domReady or similar as the committedValue object will be undefined until after the GET call has populated {{facility}}.

The ObjectObserver I have below is only handling added and changed values. The documentation for the class also shows how to do removed attributes which would require a PUT and not just a PATCH. You would probably need to modify the function declaration to pass the full {{facility}} object into formObserver() if you wanted that functionality.

Please feel free to tell me what I'm doing wrong! It works, but might not be the most optimized.

--Mark G.

<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/paper-input/paper-input.html">
<link rel="import" href="../polymer_elements/inventory-crud.html">
<script src="observer.js"></script>

<polymer-element name="facility-page" attributes="facilityId">
    <template>
        <inventory-crud endpoint="/facility/{{facilityId}}" id="facilityDetail"
            response="{{facility}}"
            on-crud-error="{{handleError}}"
            on-crud-completed="{{handleResponse}}">
        </inventory-crud>

        <div class="title">{{facility.name}}</div>
        <paper-input-decorator label="Facility Name" floatingLabel>
            <input id="facilityName" is="core-input" required value="{{facility.name}}" committedValue="{{committed.name}}">
        </paper-input-decorator>
    </template>
    <script>
        Polymer("facility-page", {
            committed: {},
            domReady: function () {
                this.$.facilityDetail.get();
            },
            handleResponse: function () {
                formObserver(this.committed, this.$.facilityDetail)
            }
        });
    </script>
</polymer-element>

(observer.js)
===================================
function formObserver(committed, crudCall) {
    "use strict";
    var observer = new ObjectObserver(committed);
    observer.open(function(added, removed, changed, getOldValueFn) {
        // respond to changes to the obj.
        Object.keys(added).forEach(function(property) {
            var paramsObj = {};
            paramsObj[property] = changed[property];
            var body = JSON.stringify(paramsObj);
            crudCall.patch(null,body);
        });
        Object.keys(changed).forEach(function(property) {
            var paramsObj = {};
            paramsObj[property] = changed[property];
            var body = JSON.stringify(paramsObj);
            crudCall.patch(null,body);
        });
    });
    Platform.performMicrotaskCheckpoint();
}
Reply all
Reply to author
Forward
0 new messages