Parham.D
Parham.D

Reputation: 1168

How to convert json string to ko.observableArray([]), array of objects?

I have a ViewModel works with knockout framework and ajax. I can save new items to the database with ajax.Save but I have problem when I want to retrieve the saved data. Here are the codes.

Codes in ViewModel:

self.Categories = ko.observableArray([]);
self.Message = ko.observable("");
elf.GetCategories = function () {
    $.ajax({
        url: "/Admin/Categories",
        cache: false,
        type: "GET",
        datatype: "json",
        contenttype: "application/json;utf8"
    }).done(function (data) {
        self.Categories(ko.mapping.fromJS(data));
    }).error(function (err) {
        self.Message("Error! " + err.status);
    });
}

console.log(JSON.stringify(data)); returns:

{"categories":[{"Id":1,"Name":"Learning","UrlSlug":"0-learning","Description":"learning"},
{"Id":2,"Name":"Topics","UrlSlug":"0-topics","Description":"posts"},
{"Id":3,"Name":"Shares","UrlSlug":"category-shares","Description":"shares"},
{"Id":4,"Name":"Projects","UrlSlug":"category-projects","Description":"project"}]}

Codes in controller is:

[HttpGet]
public ContentResult Categories()
{
    var categories = _weblogServices.Categories();
    return Content(JsonConvert.SerializeObject(new {categories}), "application/json;utf8");
}

and the problem is the self.Categories = ko.observableArray([]); is always empty without any data. I also tried these items too, but nothing changed:

ko.mapping.fromJS(data, self.Categories);
self.Categories(ko.mapping.fromJS(data));
self.Categories(ko.mapping.fromJSON(data));
ko.mapping.fromJS(data, {}, self.Categories);

I have a simple table in view :

<table id="tblCategory" class="table table-striped table-bordered 
  table-responsive table-condensed table-hover">
<thead>
  <tr>
    <th class="text-center">Name</th>
    <th class="text-center">Url Slug</th>
    <th class="text-center">Description</th>
  </tr>
</thead>
<tbody data-bind="foreach: Categories">
  <tr>
    <td><span data-bind="text: Name"></span></td>
    <td><span data-bind="text: UrlSlug"></span></td>
    <td><span data-bind="text: Description"></span></td>
    <td><button type="button" class="btn glyphicon glyphicon-pencil"
         title="Edit" data-bind="click:$data.GetSelected"></button></td>
    <td><button type="button" class="btn glyphicon glyphicon-trash"
         title="Delete" data-bind="click:$data.DeleteSelectedCategory">/button></td>
  </tr>
</tbody>
</table>

So, the question is how can I convert JSON data to observableArray([])?

UPdate: Chrome debugger says: data and Categories are not available.

Upvotes: 0

Views: 2451

Answers (1)

JotaBe
JotaBe

Reputation: 39055

You don't need to use mapping at all.

In your ajax call .done, you simply have to do this:

self.categories(data.categories);

As an observable array, categories expect an array as parameter. And according to the result of console.log(JSON.stringify(data)) being: {"categories":[{...}, {...}, ...], the array is on the categories property of the received data.

You don't need to use mapping because you simply need to show the objects inside the array, and you don't want to edit their properties. So they can be left as regular JavaScript objects, without observable properties.

Upvotes: 3

Related Questions