MVC4 WebApi Knockout JSON Invalid operand to 'in'-Collection of common programming errors
Hy, I’m stuck with this error message and I can not find an solution.
I get this message error in the Knockout JavaScript library v2.2.0:
Unhandled exception at line 1053, column 5 in localhost:port/Scripts/knockout-2.2.0.debug.js 0x800a138f – Microsoft JScript runtime error: Invalid operand to ‘in’: Object expected If there is a handler for this exception, the program may be safely continued.
It stops at this line of code in knockout-2.2.0.debug.js
if ((initialValues !== null) && (initialValues !== undefined) && !('length' in initialValues))
I use this WebApi:
public class ProductsController : ApiController
{
IEnumerable products = new List()
{
new Product { Id = 1, Name = "Tomato_Soup", Category = "Groceries", Price = 1 },
new Product { Id = 2, Name = "Yo-yo", Category = "Toys", Price = 3.75M },
new Product { Id = 3, Name = "Hammer", Category = "Hardware", Price = 16.99M }
};
public IEnumerable GetAllProducts(){
return products.AsEnumerable(); }
The scripts that I use are in a header section
@section Testscripts
{
}
And the Knockout code in the footer default script section
@section scripts
{
var apiUrl = '@Url.RouteUrl("DefaultApi", new { httproute = "", controller = "products" })';
function Product(data) {
this.Id = ko.observable(data.Id);
this.Name = ko.observable(data.Name);
this.Price = ko.observableArray(data.Price);
this.Category = ko.observable(data.Category);
}
function ProductViewModel() {
var self = this;
self.myproducts = ko.observableArray([]);
$.getJSON(apiUrl, function (allData) {
var mappedProducts = $.map(allData, function (item) { return new Product(item) });
self.myproducts(mappedProducts);
});
};
ko.applyBindings(new ProductViewModel);
}
and show the data in body:
-
The bug is in your
Product
function.You want to create an
ko.observableArray
fromdata.Price
which is a decimal value and not an array of values, which results in this not so nice exception.Change to
ko.observable
and it should work:function Product(data) { this.Id = ko.observable(data.Id); this.Name = ko.observable(data.Name); this.Price = ko.observable(data.Price); this.Category = ko.observable(data.Category); }