Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout error - Unable to process binding “foreach”

I'm having a bit of trouble seeing what's wrong with my code. More likely with the Knockout.js part... It's giving me the following error:

Message: Unable to process binding "attr: function (){return {href:website()} }"

HTML

<div class="demo-card-square mdl-card mdl-shadow--2dp" data-bind="foreach: favoriteSpot">
  <div class="mdl-card__title mdl-card--expand">
    <h2 class="mdl-card__title-text">Update</h2>
  </div>
  <div class="mdl-card__supporting-text" data-bind="text:name"></div>
  <div class="mdl-card__supporting-text" data-bind="text:location"></div>
  <a data-bind="attr: {href: website()}">Website</a>
</div>

JS

var favoriteSpotsList = [{
  venueName: "name",
  venueLocation: "address",
  website: "url",
  image: "<img src='img'",
}];


var favoriteSpot = function(data) {
  this.name = ko.observable(data.venueName);
  this.address = ko.observable(data.venueLocation);
  this.website = ko.observable(data.website);
  this.image = ko.observable(data.img);
};

var AppViewModel = function() {
  var self = this;

  /* Create array of hotspot locations. */
  this.hotSpotList = ko.observableArray([]);

  favoriteSpotsList.forEach(function(spot) {
    self.hotSpotList.push(new favoriteSpot(spot));
  });
};

ko.applyBindings(new AppViewModel());
like image 206
alphapilgrim Avatar asked Nov 19 '25 05:11

alphapilgrim


1 Answers

As @saj and @haim770 mentioned in comment, there is no favoriteSpot property on the view-model. So, the data bind should loop the hotSpotList to get the website property in it. Like below.,

data-bind="foreach: hotSpotList"

There is an easy way to identify these kind of issues, specifically while performing bindings in view

You just need add a button with click binding, The Button should be placed before the exception line.

<button data-bind="click: function () { console.log($context); }"> Context Log </button>

The above code will log the entire context in the browser console(F12). As usual you will get the exception. And this code will not resolve the issue. But this will be very helpful to identify the issue.

The above code will log the entire context of the current operation. Which holds object, property with the value.

Below are common scenarios where as you can exactly find your binding object has exceptions.

1. Properties are present/missing due to the scope level problems?

2. Whether it has case sensitive problem?

3. Your object comes under where? Is it a parent, child / Alone?

4. Human error which makes exception while binding.

There are few other ways to find the object/data in view:

1. Logs the root:

<button data-bind="click: function () { console.log($root); }"> Root Log </button>

2. Logs the Current scope data:

<button data-bind="click: function () { console.log($data); }"> Current Data Log </button>

3. Logs the parent data: (specifically helpful when we do looping)

<button data-bind="click: function () { console.log($parent); }"> Parent Log </button>

4. Logs the list of parent data: (specifically helpful when we do looping with different types of parents)

<button data-bind="click: function () { console.log($parents); }"> Parents Log </button>

5. Logs the list of parent data: (specifically helpful when we do looping and access different types of parents)

<button data-bind="click: function () { console.log(objectName.propertyName); }">Property Log </button>

For Example in your case you can do like below:

<!-- Added this button before the exception -->

<button data-bind="click: function () { console.log(favoriteSpot); }">Log </button>

<div class="demo-card-square mdl-card mdl-shadow--2dp" data-bind="foreach: favoriteSpot">
        <div class="mdl-card__title mdl-card--expand">
            <h2 class="mdl-card__title-text">Update</h2>
        </div>
        <div class="mdl-card__supporting-text" data-bind="text:name">
        </div>
        <div class="mdl-card__supporting-text" data-bind="text:location">
        </div>
        <a data-bind="attr: {href: website()}">Website</a>
    </div>

When you click the button, obviously the message will be logged as undefined in console.

Hope this helps.,

like image 199
RajeshKdev Avatar answered Nov 21 '25 19:11

RajeshKdev



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!