Igor Simic
7 years ago

How to create infinite scroll using Laravel and ngInfiniteScroll inside a div element


In this example i will describe how to use Laravel pagination to get infinite scroll effect in Angular using ngInfiniteScroll

On Angular side, this is needed:

1. install ngInfiniteScroll https://github.com/sroze/ngInfiniteScroll 
2. include it in model

var app = angular.module('MyApp', ['infinite-scroll'])

3. create service for calling the pagination on Laravel side (yes we will use pagination in this case)

<script>
app.service('infiniteScrollList',['$resource','RESOURCES','$localStorage', function($resource,RESOURCES,$localStorage){

  var infiniteScrollList = function() {
    this.items = [];
    this.busy = false;
    this.page = 1;
    this.last_page=1; // set the last page - default = 1
  };
 
 
  infiniteScrollList.prototype.nextPage = function() { 

    if (this.busy) return;
    this.busy = true;

     
    //if requested page is greater then last page don't do nothing - do not make call to backend
      if(this.page <= this.last_page){

        //select different page if user is logged in/out
       
        if( typeof $localStorage.logged_in != "undefined" ){
                 
          var codeList = $resource(RESOURCES.API+'code?page='+this.page); 
            
        }else{
       
          var codeList = $resource(RESOURCES.PUBLIC+'list?page='+this.page);
             
        }


      // make the call to API
      codeList.get().$promise.then(function(response) {
    
     
           //return response.message;
           var items = response.data;
           
         
  // set the last page based on Laravel response
           this.last_page = response.last_page;
            
           // push new items to all items array
            for (var i = 0; i < items.length; i++) {
              this.items.push(items[i]);
            }
            
            this.page++;
            this.busy = false;
   
      }.bind(this));

    }
    
     
  };

  return infiniteScrollList;


}]);
</script>

4. Include this service in controller and use it 

$scope.snippets = new infiniteScrollList();

or if you are using resolve feature it can be used there as well:
<script>
resolve:{
        resListSnippets: ['infiniteScrollList', function(infiniteScrollList){

          var initiateScroll = new infiniteScrollList();

          return initiateScroll;
 
        }]
            
      }, 
...
</script>

and in cntroller we have to include resolver and set scroll data
app.controller('ListCtrl', ['$scope', 'resListSnippets', function($scope,resListSnippets) {
   $scope.snippets = resListSnippets;
...


HTML structure

When calling infiniteScroll we have to define parent container 
infinite-scroll-container="'#scroll-container'"
and set infinite-scroll-parent atribute as well

<html><body>	
<md-content id="scroll-container">
 
		<div infinite-scroll="snippets.nextPage()" infinite-scroll-container="'#scroll-container'" infinite-scroll-parent>     

                  <div ng-repeat="item in snippets.items">

			<!-- ... loop over items -->

		  </div><!-- close ng repeat -->

		</div><!-- close infinite scroll  -->
	
	</md-content> <!-- scroll Material content block -->
</body></html>

NOTE: in this example we are using Angular Material Design but it can be applied on div element as well


On Laravel side we have to return paginated object from controller

<?php


use Response;
use App\Http\Requests;

public function getList(Request $request){

    $snippets = Snippet::paginate(3); // select only 3 elements

   return Response::json($snippets,200)->setCallback($request->callback);
}
?>

More info about Laravel pagination can be found here: https://laravel.com/docs/5.1/pagination

And we are done!