knockout mapping JSON update existing view model
Asked Answered
F

3

5

I have this JSON data coming from the server:

{"HaveNotification":false,"IsError":false,"Title":null,"Description":null}

and am trying to populate this view model via ko.mapping:

var notifyVM = {
  HaveNotification: ko.observable(true),
  IsError: ko.observable(false), 
  Title: ko.observable('Title goes here'), 
  Description: ko.observable('Description goes here'), 
}

with this code, which is called on a polling interval:

function pollNotifications() {

  $.getJSON('@Url.Action("GetNotifications", "Home")', function (data) {

    ko.mapping.fromJSON(data, notifyVM);

    setTimeout(pollNotifications, 10000);
  });
}

and this is page load code:

$(function () {

  ko.applyBindings(notifyVM);

  setTimeout(pollNotifications, 10000);
});

but its not working. If I inspect the view model after the fromJSON call the observables are not updated, they are still at their initial values.

UPDATE: Some more info... if I do this in the pollNotifications function

var newVM = ko.mapping.fromJSON(data);

I notice that the view model it creates is not the same as my one, it consists of a single observable function, whereas mine is an object with a set of observable properties.

Fleabitten answered 1/8, 2013 at 0:44 Comment(1)
try to use ko.mapping.fromJSTortuous
S
10

Try:

ko.mapping.fromJS(data, {}, notifyVM);

The two parameter form expects a view-model that was previously created with ko.mapping.fromJS. If it doesn't find one (based on looking for a specific property that fromJS adds), it assumes you're calling the fromJS(data, options) form.

The 3 parameter form removes this ambiguity.

Sha answered 24/2, 2015 at 0:20 Comment(2)
Wicked Whoot and da bomb! This one saved my day, thanks!Adalard
Worked for me as well. Thanks a lot! This should be the accepted answer.Atonality
E
0

You should use ko.mapping.fromJS instead of ko.mapping.fromJSON because $.getJSON is returning a data object (not an json string):

The success callback is passed the returned data, which is typically a JavaScript object or array as defined by the JSON structure and parsed using the $.parseJSON() method. It is also passed the text status of the response.

http://api.jquery.com/jquery.getjson/

do a console.log(data); to see the difference

Euhemerus answered 28/5, 2014 at 16:44 Comment(0)
J
-1

Have you tried manually mapping the values to the view model and seeing if that works, like this?

function pollNotifications() {
    $.getJSON('@Url.Action("GetNotifications", "Home")', function (data) {
        notifyVM.HaveNotification(data.HaveNotification);
        notifyVM.IsError(data.IsError);
        notifyVM.Title(data.Title);
        notifyVM.Description(data.Description);

        setTimeout(pollNotifications, 10000);
    });
}

If the above does not work, then you know it is an issue with your data; otherwise the mapping is not happening correctly with ko.mapping.fromJSON().

Judiejudith answered 1/8, 2013 at 0:58 Comment(2)
Yes, that works if I manually update the values. But I would really like to know why the ko.mapping method is not working. I suspect the JSON data structure is not matching up with my view model, but I can't see where or why.Fleabitten
Have you tried ko.mapping.fromJS(data, notifyVM); instead of the fromJSON() function? I am wondering if the fromJSON() function is disqualifying your data as being interpreted as JSON.Judiejudith

© 2022 - 2024 — McMap. All rights reserved.