Search code examples
javascriptknockout.jsoracle-jet

knockout JS unable to access the elements of observableArray


I have created knockout observable array and added element as below,

define(['ojs/ojcore', 'knockout', 'jquery', 'ojs/ojtable', 'ojs/ojarraytabledatasource', 'ojs/ojrouter'],
 function(oj, ko, $) {

    function CustomerViewModel() {
      var self = this;
      self.data = ko.observableArray([]);

      var getDataUrl = <rest-api-url>
      var fetchDataPayLoad = JSON.stringify(<json_data>);

      self.fetchData = function(fetchDataPayLoad, fetchDataCallBack) {
             $.ajax({
               url: getDataUrl,
               data: fetchDataPayLoad,
               type: 'POST',
               contentType: 'application/json',
               success: fetchDataCallBack,
               error: function (jqXHR, textStatus, errorThrown) {
                 console.log('Error during fetch');
               }
             });
           };

      function fetchDataCallBack(fetchedData){
             fetchedData.hits.hits.forEach(function(e){
                 var value1 = e._id;
                 value2 = e._value;
                 value3 = e.name;
                 value4 = e.testdata;
                 self.data.push({
                   prop1: value1,
                   prop2: value2,
                   prop3: value3,
                   prop4: value4
                 });
               });
             });
           };
           var fetchDataRun = this.fetchData(fetchDataPayLoad, fetchDataCallBack);
           console.log(self.data());
}
    return new CustomerViewModel();
}
);

When am trying to check the lenght of the observableArray getting 0 always and when I print the same got data as below on console,

>[]

and when I expand,

>0: {prop1: "value11", prop2: "value12", prop3: "value13", prop4: "value14"}
>1: {prop1: "value21", prop2: "value22", prop3: "value23", prop4: "value24"}

Not sure what am doing wrong/missing here, May I know how to access the observableArray element?


Solution

  • Change the location of your console.log.

    function fetchDataCallBack(fetchedData){
        fetchedData.hits.hits.forEach(function(e){
            var value1 = e._id;
            value2 = e._value;
            value3 = e.name;
            value4 = e.testdata;
            self.data.push({
                prop1: value1,
                prop2: value2,
                prop3: value3,
                prop4: value4
            });
        });
        console.log(self.data());
    });
    

    Your Ajax call is asynchronous, meaning that the callback function executes only after the call is complete. Currently you are using console.log while the Ajax call is still running in the background and hence it shows as empty. See here for a visual explanation.