3
votes

EDIT: This only appears outside of Chrome

I'm using KO to fill in elements using foreach bindings. On the other side of the coin, I've got Polymer loaded up to make use of Google's Material Design styling.

The issue is that there seems to be an assertion in the platform.js file (Polymer) that is trying to take over the data-bind even though Polymer doesn't use the data-bind attribute.

Wondering if anybody has had any experience using both of these, or any suggestions? Error is below:

Error: Unable to process binding "template: function (){return { foreach:sessions} }" Message: Assertion failed

JSFiddle: http://jsfiddle.net/Rmp6c/3/

EDIT: So I've setup the debug version, and it appears that inside ShadowDOM/src/wrappers.js on line 31 there is an assert(b) function that is being passed a boolean. This is called 100s of times by a Node.js file, and to fix this looks like it would require a fairly large rewrite.

My fix for this has been to use jQuery to insert the DOM element with the foreach binding, and then apply my KO bindings inside a $(document).ready(function() {}); tag. This appears to work on all browsers.

2
Can you post some more context? This is the whole message, don't you have a stackstracte where is the error coming? How do you use polymer? Can you maybe create a jsfiddle with your current setup? - nemesv
Polymer is minified - so it simply says line 12. The only setup needed is Polymer with a Knockout foreach. I'll post a jsfiddle shortly - Xarus
I don't see any error in your fiddle, it is working completly fine... - nemesv
Are you using Firefox? - Xarus
also - that's a nasty fix you had to do :) I'd suggest answering your own question and marking it accepted so it gets out of the "unanswered" queue - Milimetric

2 Answers

3
votes

If anyone has this issue, it is because you are using the ko.applyBindings(viewModel) method, and in here knockout uses window.document.body to get the node, which in turn misses the shadowDOM polyfill which webcomponents.js uses.

To get around this, you have two options, use the second overload of the apply bindings method - you'll probably get a successfully wrapped node this way.

Alternatively, you can load this shim immediately after the knockout declaration (some boilerplate borrowed from knockout.validation:

(function (factory) {
    // Module systems magic dance.

    if (typeof require === "function" && typeof module === "object") {
        // CommonJS or Node: hard-coded dependency on "knockout"
        factory(require("knockout"));
    } else if (typeof define === "function" && define["amd"]) {
        // AMD anonymous module with hard-coded dependency on "knockout"
        define(["knockout"], factory);
    } else {
        // <script> tag: use the global `ko` object, attaching a `mapping` property
        factory(ko);
    }
}(function (ko) {

    if (typeof (ko) === undefined) { throw 'Knockout is required, please ensure it is loaded before loading this shim'; }

    if (WebComponents && WebComponents.flags.shadow && ShadowDOMPolyfill) {

        var _originalApplyBindings = ko.applyBindings;

        ko.applyBindings = function (viewModel, rootNode) {
            if (rootNode) {
                rootNode = ShadowDOMPolyfill.wrapIfNeeded(rootNode);
            } else {
                rootNode = ShadowDOMPolyfill.wrapIfNeeded(window.document.body);
            }
            _originalApplyBindings(viewModel, rootNode);
        }
    }
}));

Hopefully this helps anyone with the same issue.

0
votes

My fix for this has been to use jQuery to insert the DOM element with the foreach binding, and then apply my KO bindings inside a $(document).ready(function() {}); tag. This appears to work on all browsers.

While this isn't a great fix - it is the only one that has worked properly. I've reached out to Steve Sanderson of KnockoutJS and believe he's looking into it. The reason that I went with this fix over just using Knockout Custom components, is that the Polymer components offer Material Design as per Google's new design specs, and the web front-end that I'm building is intrinsically tied to my company's mobile application, so I wanted to maintain a cohesive design.