Emberjs loadmore like here in discuss,emberjs

Do you have any good solutions for emberjs pagination and loadmore functionality

1 Like

Iā€™ve seen several different implementations of ā€˜Load Moreā€™ with Ember.js - @bantic has a good example of this on github https://github.com/bantic/ember-infinite-scroll

I tried these example but Itā€™s not working with emberjs 1.4 and emberdata 1

also I need a solution to work with real sever not a fake one

The JSBin example is outdated. It is using events object instead of actions object. I updated the JSBin example with Ember.js v1.4.0 and it works as expected with a few minor tweaks.

http://jsbin.com/famer/1/

If you are still having issues, put together a JSBin example of what youā€™re trying to do that isnā€™t working and I can take a look.

the problem is with loading data from the server in my profilesRoute Remon.ProfilesRoute=Ember.Route.extend({

	model: function(){
return this.store.findQuery("profile", {
    page:1
});
//rest of code...
 });

I have rails pagination on server back-end I want to append new data with page increase and push for example when I click load more I want to append the new data retrieved from page2 and so on

I have a super simple ā€œload moreā€ mixin I use with my posts route for my blog app (pixelhandler.com)

The RecordChunksMixin code is here: https://github.com/pixelhandler/blog/blob/master/client/app/mixins/record_chunks_mixin.js

Here is the route (index) that uses the mixin: https://github.com/pixelhandler/blog/blob/master/client/app/routes/index_route.js#L5-L13

Here is a simple integration test for that feature on my blog app: https://github.com/pixelhandler/blog/blob/master/client/tests/integration/index_test.js#L18-L33

pagination in your blog is what exactly what I want ,but I am getting that error when I implemented your ixin in my application

Uncaught TypeError: Object [object Object] has no method ā€˜refreshā€™

refresh is a method of a route instance, Route - 4.6 - Ember API Documentation

i changed the code to work with pagination by page but it still throwing the same error

 App.RecordChunksMixin = Ember.Mixin.create({

  resourceName: null,

   page: 1,


   beforeModel: function () {
     this.set('page', this.get('page'));
   } ,

   model: function () {
     var query = { page: this.get('page') };

   return this.store.findQuery(this.get('resourceName'), {
      page: this.get('page')
      });
   },
   afterModel: function (collection) {

    this.set('meta', this.store.metadataFor(this.get('resourceName')));
    var loaded = this.get('loadedIds');

   collection.mapBy('id').forEach(function (id) {
    loaded.push(id);
   });
   this.set('loadedIds', loaded.uniq());
  return collection;
  },


   meta: null,
     loadedIds: [],

  setupController: function (controller) {
    var collection = [];
    this.get('loadedIds').forEach(function (id) {
     var model = this.store.getById(this.get('resourceName'), id);
    if (model) {
     collection.push(model);
    }
   }.bind(this));
    controller.set('hasMore', this.get('hasMore'));
    this._super(controller, collection);
   },

   hasMore: function () {
   return this.get('loadedIds').length < this.get('meta.total');
  }.property('meta.total').volatile()
 });

and my profiles_route

  App.ProfilesRoute=Ember.Route.extend(App.RecordChunksMixin, {
     resourceName: 'profile',

   actions: {
   showMore: function () {
     this.refresh();
   }
  }
 });

when I click load more link

 Uncaught TypeError: Object [object Object] has no method 'refresh'

the problem was that refresh method is in version 1.4 not in 1.3 after upgrading to 1.4 and clicking show more

  Uncaught Error: Assertion Failed: TypeError: Cannot read property 'container' of undefined 

@Remon_Amin here is the template Iā€™m using for the button https://github.com/pixelhandler/blog/blob/master/client/app/templates/has-more-button.hbs it just sends an action that is responded to on the router. I changed my index controller to also respond to the action https://github.com/pixelhandler/blog/blob/master/client/app/controllers/index_controller.js but return true to bubble up to route here https://github.com/pixelhandler/blog/blob/master/client/app/routes/index_route.js And the mixin here https://github.com/pixelhandler/blog/blob/master/client/app/mixins/record_chunks_mixin.js

The result is that when user clicks ā€œshow moreā€ a request is make like: /posts?offset=5&limit=5 then when clicked again /posts?offset=10&limit=5 each time the routeā€™s afterModel hook is called the loadedIds property is populated so the setupController method can use store.getById and give each loaded records to the controller.

The bower file shows what versions Iā€™m using: https://github.com/pixelhandler/blog/blob/master/client/bower.json

Iā€™m not sure why you get the error about the container I didnā€™t reference that at all. I know the code works in production, so it sounds like youā€™re getting close.

@pixelhandler, in my application I have an initial list of profiles comes from the rails server

   model: function(){
return this.store.findQuery("profile", {
    page:1
 });
} 

I have a metadata of total pages and the current page what I need is that when you click load more a request send to /api/profiles?page=2 and append the results to the model ,and so on till reached the current_page === total number of pages

@Remon_Amin the flag I use to know if the show more button can be used compares the count of ids to the meta.total see: https://github.com/pixelhandler/blog/blob/master/client/app/mixins/record_chunks_mixin.js#L56-L58 which is based on the JSON payload sent from the server

    "meta": {
        "offset": 0,
        "limit": 5,
        "sortBy": "date",
        "order": "desc",
        "total": 62
    },

I based the meta info on Handling Metadata - Ember Data - Ember Guides this is where the afterModel hook gets the meta data: https://github.com/pixelhandler/blog/blob/master/client/app/mixins/record_chunks_mixin.js#L29

I implement a solution ,it work great and I will do some modifications for still loading and error

   Remon.ProfilesRoute=Ember.Route.extend( {
   beforeModel: function(){
 this.controllerFor("profiles").set("no_more",null);	
this.controllerFor("profiles").set("current_page",1);
  },
model: function(){
  return this.store.findQuery("profile", {
page:1
  });
},


   actions: {
    showMore: function () {  

	  items = Em.A(),
   	  firstpage = this.controllerFor("profiles").get("current_page"),
	  newpage =firstpage +1,
	  total =this.controllerFor("profiles").get("total_pages");



$.ajax({
   url: 'http://localhost:3001/api/profiles.json?page='+newpage,
 async: false,
 success: function(data){

	items =data.profiles;
  }

});
 this.modelFor("profiles").pushObjects(items);

this.controllerFor("profiles").set("current_page",newpage);
 if (newpage== total){
	this.controllerFor("profiles").set("no_more",true);
}


     }
   }


 });

and in my controller

   Remon.ProfilesController =Ember.ArrayController.extend({
current_page :1,
no_more: null,
total_pages : function(){
	return this.store.metadataFor("profile").total;
}.property()


 });

in profiles.hbs

   {{#if no_more}}
  <p>
  	no more profiles
</p>
   {{else}}
  <a href='#' {{action 'showMore'}}>Load more data (manually)</a>
  {{/if}}