Diego Unanue
Diego Unanue

Reputation: 6826

KnockOut Unable to parse bindings

I was reading other answers but I can't find the solution, the error says: Error: Unable to parse bindings. Message: ReferenceError: AdvertisementLegs is not defined; Bindings value: foreach: AdvertisementLegs, and I cant find why, becouse its defined in the model:

Here is the models

Main Model.js

self.selectedAd = ko.observable();

    self.selectAd = function (item, data) {
        self.selectedAd = ko.observable(new AdvertisementMgr());

        self.advertisementManager().getAdvertisementById(item);
        $('#windowEditAd').jqxWindow('open');
    };

Advertisement Model.js

var self = this;

//URLS

self.CompanyName = ko.observable("");
//Lists
self.AdvertisementLegs = ko.observableArray();

    self.getAdvertisementById = function (dataItem) {
    $.ajax({
        cache: false,
        url: mViewModel.apiUrl + 'Advertisement',
        type: "GET",
        contentType: "json",
        dataType: "json",
        data: {
            adId : dataItem.AdvertisementId()
        },
        success: function (data) {

            mViewModel.selectedAd(data);
        },
        error: function (xhr, status, error) {
            alert(error.message);
        }
    });
};

the json response is:

CompanyName
    "Flotsum Strategies, Inc"


AdvertisementLegs
    [Object { AdvertisementLegId=6, Action="BUYER", Volume=1, más...}]

0
    Object { AdvertisementLegId=6, Action="BUYER", Volume=1, más...}

AdvertisementLegId
    6

Action
    "BUYER"

Price
    0

AdvertisementId
    4

AdvertisementLegType
    "TL"

The view is:

    <div data-bind="with: $root.selectedAd">

    <span data-bind="text: CompanyName"></span>     
    <input data-bind="value: CompanyName" type="text" class="txt4 leg_data_vol1" style="width: 50px; text-align: center;" id="leg_data_vol1" />




    <table border="0" cellspacing="0" cellpadding="0" class="volaxe-table">
        <tbody data-bind="foreach: AdvertisementLegs ">
            <tr >
                <td>

                    lalla

                    <input data-bind="value: Volume" type="text" class="txt4 leg_data_vol1" style="width: 50px; text-align: center;" id="leg_data_vol1" />
                </td>
            </tr>

        </tbody>
    </table>
 </div>

CompanyName has no problem the issue is with the array it says Message: ReferenceError: AdvertisementLegs is not defined. Why it says that it cant bind it if its in the model and it has results?

Upvotes: 1

Views: 5102

Answers (2)

nwayve
nwayve

Reputation: 2331

self.selectedAd = ko.observable(new AdvertisementMgr());

This is no good because after you applyBindings and then call selectAd, you overwrite your observable reference with a new observable. You want:

self.selectedAd(new AdvertisementMgr());// Or do you?

Sure this isn't supposed to be:

self.selectedAd(new Advertisement()); // ?

I also noticed in your getAdvertisementById method, you do this:

mViewModel.selectedAd(data); // No bueno

self.selectAd function fires off and sets the selectedAd to a new AdvertisementMgr. Then you getAdvertisementById. You make your ajax call and on success, you set the selectedAd again, but you're doing it with the raw data object that comes back.

function Advertisement(data) { ... }

Then

myViewModel.selectedAd(new Advertisement(data));

In your Advertisement model, ensure all properties are being set to default values and also ensure properties that need to be observables are being set as observables.

Upvotes: 2

xdumaine
xdumaine

Reputation: 10329

This is because when the initial bindings are applied, selectedAd defined as null when created as ko.observable(), and doesn't have any property AdvertisementLegs until it is set to new AdvertisementMgr() in selectAd.

You should check that selectedAd is not null before attempting to bind to it's properties. You could wrap your entire <div data-bind="with: $root.selectedAd"></div> container with a knockout if to ensure that it's non null before being rendered/bound.

So just wrap your whole markup with <!-- ko if: $root.selectedAd() --><!-- /ko --> which unwraps selectedAd, makes sure it's not null, and doesn't attempt to render until that element is non null.

<!-- ko if: $root.selectedAd() -->
<div data-bind="with: $root.selectedAd">

  <span data-bind="text: CompanyName"></span>     
  <input data-bind="value: CompanyName" type="text" class="txt4 leg_data_vol1" style="width: 50px; text-align: center;" id="leg_data_vol1" />
  <table border="0" cellspacing="0" cellpadding="0" class="volaxe-table">
    <tbody data-bind="foreach: AdvertisementLegs ">
        <tr >
            <td>
                lalla
                <input data-bind="value: Volume" type="text" class="txt4 leg_data_vol1" style="width: 50px; text-align: center;" id="leg_data_vol1" />
            </td>
        </tr>

    </tbody>
  </table>
</div>
<!-- /ko -->

Upvotes: 1

Related Questions