Material angular infinite scroll with $http request

11,038

This one works:

plnkr

  • getItemAtIndex returned the index and not the item
  • if you inspected what you pushed, you'd see that at line 33 in my plunkr I concat obj.data, not plain obj
(function () {
    'use strict';
    angular.module('infiniteScrolling', ['ngMaterial'])
      .controller('AppCtrl', function ($scope, $http) {
          // In this example, we set up our model using a plain object.
          // Using a class works too. All that matters is that we implement
          // getItemAtIndex and getLength.
          var vm = this;
          vm.infiniteItems = {
              numLoaded_: 0,
              toLoad_: 0,
              items: [],

              // Required.
              getItemAtIndex: function (index) {
                  if (index > this.numLoaded_) {
                      this.fetchMoreItems_(index);
                      return null;
                  }
                  return this.items[index];
              },

              // Required.
              getLength: function () {
                  return this.numLoaded_ + 5;
              },

              fetchMoreItems_: function (index) {
                  if (this.toLoad_ < index) {
                      this.toLoad_ += 5;
                      $http.get('items.json').then(angular.bind(this, function (obj) {
                          this.items = this.items.concat(obj.data);
                          this.numLoaded_ = this.toLoad_;
                      }));
                  }
              }
          }
      })
})();
Share:
11,038
Asieh Mokarian
Author by

Asieh Mokarian

I've been a software developer since 2004 and during more than 10 years of experience, I’ve been involved in various projects in different fields such as software development, network security and network technologies. Recently, I’m focused on C#, Web API and front-end technologies as a full-stack developer.

Updated on June 08, 2022

Comments

  • Asieh Mokarian
    Asieh Mokarian almost 2 years

    I'm using md-virtual-repeat directive of Angular Material to have an infinite scroll, and I need to replace it's demo $timeout function with a $http request. But I can't get to the right solution. In the code below, infinite scroll works fine but doesn't show the data from http request. The problem is that I don't know the way of binding $http result to infiniteItems.

    Here is the plunker.

    Index.html

    <body ng-app="infiniteScrolling" class="virtualRepeatdemoInfiniteScroll">
    <div ng-controller="AppCtrl as ctrl" ng-cloak>
        <md-content layout="column">
            <md-virtual-repeat-container id="vertical-container" flex>
                <div md-virtual-repeat="item in ctrl.infiniteItems" md-on-demand
                     class="repeated-item" flex>
                    {{item.id}}
                </div>
            </md-virtual-repeat-container>
        </md-content>
    </div>
    </body>
    

    JS:

    (function () {
    'use strict';
    angular
      .module('infiniteScrolling', ['ngMaterial'])
      .controller('AppCtrl', function ($timeout,$scope,$http) {
         this.infiniteItems = {
              numLoaded_: 0,
              toLoad_: 0,
              items:[],
              getItemAtIndex: function (index) {
                  if (index > this.numLoaded_) {
                      this.fetchMoreItems_(index);
                      return null;
                  }
                  return index;
              },
              getLength: function () {
                  return this.numLoaded_ + 5;
              },
              fetchMoreItems_: function (index) {
                   if (this.toLoad_ < index) {
                      this.toLoad_ += 20;
    
                      $http.get('items.json').success(function (data) {
                          var items = data;
                          for (var i = 0; i < items.length; i++) {
                              this.items.push(items[i].data);
                          }
                          this.numLoaded_ = this.toLoad_;
                      }.bind(this));
                  }
              }
          };
       });
    })();
    
  • Asieh Mokarian
    Asieh Mokarian over 8 years
    Thank you, It works. But I don't know why for toLoad_+=20 , when I go down the scroll the data loads with a big delay, very down never loads not the same for toLoad_+=10 .
  • Alec
    Alec over 8 years
    Well, actually it creates element in the DOM but since your api returns 5 elements, iirc, it has not enough data to initialize, so they are blank/empty.
  • Asieh Mokarian
    Asieh Mokarian over 8 years
    Thanks, you are right. I just wants to add one more point: I think replacing data with obj.data is not part of the solution as I was using success instead of then and it returns data not result, but using concat is part of the solution. Because when I remove that the code not work correctly. It has a downside as it store all data (all out of view data) in memory not only the data in view.
  • Alec
    Alec over 8 years
    @A.M About the success vs then solution I presented: success and errorhave been deprecated
  • lunacafu
    lunacafu about 8 years
    This actually works for me, except that I would want the list to stop scrolling once all the data is displayed. This solution repeats the json.data from the start again.
  • rcheuk
    rcheuk about 8 years
    anyone figure out how to stop the scrolling?
  • Raju Donthula
    Raju Donthula almost 8 years
    And your saying it creates element in the DOM and if we get lesser records that shows blank records. So how can I remove or stop generating those blank records. Can you please help...