Kaushik C
Kaushik C

Reputation: 114

How to append json and display result using ajax (Observable array)

Whenever i click that Add button it should fetch json data using ajax and should append that to my Observable arrray and in html also i want to append that.

Here is my code

    function ProductViewModel() {
      var self = this;
      self.ProductList = ko.observableArray([]);

      self.GetProducts = function (){
        $.ajax({
          type: "POST",
          dataType: "json",
          url: 'data.json',
          //my json data is 
          //{"1":{"name":"user","productname":"hello"},"2":{"name":"user2","productname":"hello2"}}

          
          success: function (data) {
            console.log(self.ProductList());
              self.ProductList($.map(data, function (product) {
                 return new ProductDetailsViewModel(product);
            }));
          }
        });
      }
     self.GetProducts();
    }

    function ProductDetailsViewModel(data){
      var self = this;
      self.Name= ko.observable(data.name);
      self.PrdouctName= ko.observable(data.productname);
    }

    ko.applyBindings(new ProductViewModel());
  <script
  src="https://code.jquery.com/jquery-2.2.4.min.js"
  integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
  crossorigin="anonymous"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js" charset="utf-8"></script>


  <h1 data-bind="foreach:ProductList">
     <div data-bind="text:Name"></div>
     <div data-bind="text:PrdouctName"></div>
  </h1>

Thanks in advance!

Upvotes: 0

Views: 155

Answers (3)

MKougiouris
MKougiouris

Reputation: 2861

Do NOT user your current solution like:

$.map(data, function (product){
               self.ProductList.push(new ProductDetailsViewModel(product));
             })

Just because it works does not mean that it is ok. You should $.map when you transform data to output them in a different sequence. In your case you should use $.each, as you want to push "each" item in the array.

Both map and each work similarly, in the sense that they will iterate an array and perform a callback on the items, but semantic-wise you should always use the proper method to denote your actual intentions.

If i were you i would do something like this:

ko.utils.arrayForEach(data, function(p) {
       self.ProductList.push(new ProductDetailsViewModel(p));
});

Two concepts to note:

a) Learn and use knockouts utility functions, they come in hand and outperform jquery's alternatives ( from what i see/know)

b)You should also mind how you update your list, depending on the size of the items you are adding. If you are adding a small amount of items on each callback the above should be enough. On the other hand if performance starts to become a trouble you can work on the underlying array and at the end of your data insertion you can trigger a knockout-update!

This would work like so:

var underlyingArray = self.ProductList();
ko.utils.arrayForEach(data, function(p) {
       underlyingArray.push(new ProductDetailsViewModel(p));
});
self.ProductList.valueHasMutated();

Upvotes: 1

Kaushik C
Kaushik C

Reputation: 114

I Got the answer!! This is what i want in success method

   `success: function (data) {
             $.map(data, function (product){
               self.ProductList.push(new ProductDetailsViewModel(product));
             })
          }`

Upvotes: 1

Ben Hanna
Ben Hanna

Reputation: 129

If you're meaning to append to the observable array then you can use the push function.

success: function (data) {
  console.log(self.ProductList());
  $.each(data, function (product) {
    self.ProductList.push(new ProductDetailsViewModel(product));
  }));
}

Upvotes: 1

Related Questions