0

Upon click of "Add" button, result from db will be fetched. I want this result to be populated in observableArray or computed (computed for future).

I am clueless on how to populate the observable array. Below is the code for ajax call

KNOCKOUTJS

self.addToCartViaProdList = function (item, event) 
{
    /*get current item index*/
    /*in dom element $index() is enough but in viewModel a context is to be obtained*/
    var context = ko.contextFor(event.target);
    var index = context.$index();
    var incQty = self.prodList()[index].ProductQty();
    var prodID = self.prodList()[index].ProductID();

    var verProdInCombo = ko.toJS({"prodID":prodID});
    //check product in combos
    $.ajax
    ({
        url: '**************ProdID.php', 
        type: "post",
        data: verProdInCombo,
        success: function(result) 
        {
            /*The result is in below format*/
            /***************
            "{"ComboName":"SinglePack","ComboItemsName":"Aloo Tikki Burger,Mango Lassi,Tomato Soup","ComboItemsID":"101_1_11,1105_11_110,901_9_90","ComboTotalPrice":"90.25"}"
            ********************/
        }, 
        error: function(xhr, status){
            alert(xhr);
            alert(status);
        }
    });
};

I am getting the success result, but all my attempts to put this data in observableArray has not yielded any fruitful result.

I have tried saving the result in localSession. And then using a computed variable to pick values from that localSession,

Then I have tried to use ko.mapping.fromJS(result), this didnot work either

I want to display the list as received from server in a div as follows:

HTML CODE

<div class="comboSeg" >
    <div data-bind="foreach: comboDataList">
        <div data-bind="text: ComboName">
        </div>
        <div data-bind="text: ComboItemsName">
        </div>
        <div data-bind="text: ComboTotalPrice">
        </div>
    </div>
</div>

The different version of knockoutjs tried are:

VERSION 1: Saving data in local session and using computed

self.comboDataList = ko.computed(function()
{
    var comboDataItems = [];
    if (self.comboValChange() == "DO" && localStorage.getItem("comboDataItem") != null)
    {
        var dataSaved = localStorage.getItem("comboDataItem");
        comboDataItems = ko.utils.arrayMap(dataSaved, function(item)
        {
            return new ComboList(item.ComboName, item.ComboItemsName, item.ComboItemsID, item.ComboTotalPrice);
        });

        comboDataItems.push(dataSaved);
    }

    return comboDataItems;
},this);

//Ajax call is as follows:

    $.ajax
    ({
        url: '***************ProdID.php', 
        type: "post",
        data: verProdInCombo,
        success: function(result) 
        {
            localStorage.removeItem("comboDataItem");
            localStorage.setItem("comboDataItem",result);
            //Forcing the computed function to be called, just a workaround
            self.comboValChange("");
            self.comboValChange("DO");
        }, //Result will contain whatever server will send back as a mesage
        error: function(xhr, status){
            alert(xhr);
            alert(status);
        }
    });

VERSION 2 : Pushing the success msg received in comboDataList

    $.ajax
    ({
        url: '*************ProdID.php', 
        type: "post",
        data: verProdInCombo,
        success: function(result)
        {
            self.comboDataList.push(result);
            //Also tried below one
            //self.comboDataList.push(ko.toJS(result));
        }, //Result will contain whatever server will send back as a mesage
        error: function(xhr, status){
            alert(xhr);
            alert(status);
        }
    });

Now I have enabled the denug in browser I got this error message for both the versions:

Error : Uncaught ReferenceError: Unable to process binding "text: function (){return ComboName }" Message: ComboName is not defined

4
  • 1
    You mention having tried two versions for the success handler function, but haven't included the code or the details as to why it didn't work or what error it gave. Please include those so we can help you fix the problem. Commented Nov 20, 2015 at 8:54
  • you json looks just fine check this sample here jsfiddle.net/LkqTU/27832 . more info is appreciated . Commented Nov 20, 2015 at 9:04
  • @Jeroen: I did not get any error. Somehow the comboDataList remain empty. What I want to know that after each ajax call does the whole View model refreshes itself? Currently I am out of office. I will attach the code couple of hours later. Apologies for not doing the same rightaway. Commented Nov 20, 2015 at 10:23
  • Well, at this moment, the list would remain empty because all code in the success handler is commented out ;-). If you add the code it's quite likely we'll be able to help you. - In any case, to answer your other question: Knockout will update the view automatically if you change observables, but not if you overwrite a property/variable that contains an observable with a new one. (Again though: easier to explain in the context of actual code.) Commented Nov 20, 2015 at 10:37

2 Answers 2

2

Just plug the observableArray in as the success function of your Ajax call:

$.ajax
({
    url: '**************ProdID.php', 
    type: "post",
    data: verProdInCombo,
    success: self.comboDataList, 
    error: function(xhr, status){
        alert(xhr);
        alert(status);
    }
});

That assumes you don't need to update the individual elements inside rows of the array.

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the answer but I am getting below error <Uncaught ReferenceError: Unable to process binding "text: function (){return ComboName }" Message: ComboName is not defined>
Though in the debug I can see ComboName is present in the json received as string.
Show us the JSON you're getting from the server. It is the most important information for answering your question.
This is the json I am getting in string format <"{"ComboName":"SinglePack","ComboItemsName":"Aloo Tikki Burger,Mango Lassi,Tomato Soup","ComboItemsID":"101_1_11,1105_11_110,901_9_90","ComboTotalPrice":"90.25"}">
Possibly adding dataType:'json' to your ajax parameters will help. You need to know whether success is getting the string value or the JS object. Play with it.
|
0

This is how I got it working, guess this is not the best method. Simply pushing the success JSON object into observableArray was not reflected in my html page, hence I used computed to get it done.

The KNOCKOUT Code is

self.comboDataList = ko.computed(function()
{
    var comboDataItems = [];
    //self.comboValChange() an observable variable just to invoke the computed function everytime there is update
    if (self.comboValChange() == "DO" && localStorage.getItem("comboItems") != null)
    {
        var dataSaved = ko.utils.parseJson(localStorage.getItem("comboItems"));
        comboDataItems = ko.utils.arrayMap(dataSaved, function(item)
        {
            return new ComboList(item.ComboName, item.ComboItemsName, item.ComboItemsID, item.ComboTotalPrice);
        });

        comboDataItems.push(dataSaved);
    }

    return comboDataItems;
},this);


//The ajax call
    $.ajax
    ({
        url: '**************ProdID.php', 
        type: "post",
        data: verProdInCombo,
        dataType:'json',
        success: function(result) 
        {
            //using localStorage to store the result
            localStorage.removeItem("comboItems");
            localStorage.setItem("comboItems", ko.toJSON(result));
            //updating so that everytime computed is called
            self.comboValChange("");
            self.comboValChange("DO");
        }, //Result will contain whatever server will send back as a mesage
        error: function(xhr, status){
            alert(xhr);
            alert(status);
        }
    });

The HTML is:

    <div class="comboSeg" >
        <div data-bind="foreach: comboDataList">
            <div data-bind="text: ComboName">
            </div>
            <div data-bind="text: ComboItemsName">
            </div>
            <div data-bind="text: ComboTotalPrice">
            </div>
        </div>
    </div>

The structure of JSON is:

"{"ComboName":"SinglePack","ComboItemsName":"Aloo Tikki Burger,Mango Lassi,Tomato Soup","ComboItemsID":"101_1_11,1105_11_110,901_9_90","ComboTotalPrice":"90.25"}"‌

Hence the view model will be:

function ComboList(ComboName, ComboItemsName, ComboItemsID, ComboTotalPrice)
{
    this.ComboName = ko.observable(ComboName);
    this.ComboItemsName = ko.observable(ComboItemsName);
    this.ComboItemsID = ko.observable(ComboItemsID);
    this.ComboTotalPrice = ko.observable(ComboTotalPrice);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.