error in live shopping cart example on website

34 views
Skip to first unread message

Ankur

unread,
Dec 24, 2011, 10:53:53 AM12/24/11
to KnockoutJS
There is a slight error in the shopping cart example and I don't
understand why. I am trying to do something simlilar.

Here are steps:

Working:
1. Select category
result: products appear
2. Select category back to 'select', which makes category 'undefined'
result: products disappear (as they should with the if binding)

Not Working
1. Select category
result: products appear
2. Select a product
3. Select category back to 'select' which makes category 'undefined'
result: products stay, and we get this javascript error:
Uncaught Error: Unable to parse bindings.
Message: TypeError: Cannot read property 'products' of undefined;
Bindings value: options: category().products, optionsText: "name",
optionsCaption: "Select...", value: product

Wanted to know if anyone could explain why this is happening. From
what I see, the if binding should handle this.

rpn

unread,
Dec 24, 2011, 1:34:58 PM12/24/11
to knock...@googlegroups.com
Thanks for pointing this out.  I just fixed the issue (you may need to refresh the page).

Here was what was happening:
- When category was set to null for a line by choosing the "Select..." line, then this subscription kicked in before the "if" binding had a chance to run.

    // Whenever the category changes, reset the product selection
    this.category.subscribe(function() {
        this.product(undefined);
    }, this);

- When "product" was set to undefined, this triggered the bindings on the select element immediately (again prior to the "if" binding running on the parent) as it has the value binding bound to "product".   This runs all of the bindings in that data-bind.  At this point, "category" is already null and so when it tried to do "category().products" it would error out.

Kind of a tricky timing issue where a dependency on the inner binding triggered it prior to the parent binding running.

To solve it, you could set product to undefined in a setTimeout, to let the current execution finish, but setTimeouts are kind of a last resort for me.  

You also could change the binding to be "category() ? category().products : null", but that is kind of strange looking inside of the "if" block.  

Instead, I changed the "if" binding to a "with" binding and updated the references appropriately.  In that case, the scope won't change until the "with" binding runs, so it won't have the same error binding it (although it does re-run the inner bindings that will be thrown away, but not a performance issue in this case).  


Ankur

unread,
Dec 24, 2011, 2:12:21 PM12/24/11
to KnockoutJS
Wow, it makes sense after you explained it! I didn't realize the
inner binding was being evaluated first (but that's clearly what the
error message was saying).

I was using that example to build a 4 level deep nested dropdown.
Would have been a nightmare without knockout. It is working very
smoothly now, thank you.

Ankur
Reply all
Reply to author
Forward
0 new messages