Monaca Onsen UI Discord Chat Github Repo

lazy-repeat refresh method is undefined



  • Hello I have an Angular JS application where a list is defined as follows

    <ons-page ng-controller="AllItemsController">
    <ons-list>
    <ons-list-item ons-lazy-repeat="lazyLoadDelegate"
    class="list__item__line-height" 
    ng-class="{selected_list_row:isItemSelected(item),selected:item.selected}">
     <span>{{item.name}}</span>
    </ons-list-item>
     </ons-list>
    </ons-page>
    

    The controller and the delegate are defined as follows

    (function () {
        'use strict';
        angular
            .module('MyApp')
            .controller('AllItemsController', AllItemsController);
    
    AllItemsController.$inject = ['$scope']; 
       
    AllItemsController($scope) {    	
        	$scope.lazyLoadDelegate = {
          	      configureItemScope: function(index, itemScope) {
          	    	if(index < itemsList.length ){
          	    		itemScope.item = $scope.itemsList[index];
          	    	}
          	      },
          	      countItems: function() {
          	        return $scope.itemsList.length;
          	      },
                  calculateItemHeight: function() {
                      return  44;
                  }
        	};
    $scope.$on(EventManager.EVT_ALL_ITEMS_FETCHED, function(event,data){
        		$scope.lazyLoadDelegate.refresh();
        		$scope.$apply();    		
        	});
    }// AllItemsController
        	
    })();
    

    When the event fires and $scope.lazyLoadDelegate.refresh is called I get an error that refresh method is undefined.
    Examining the $scope.lazyLoadDelegate variable in the debugger shows that the refresh method is indeed not there
    Also when I put breakpoints in any delegate methods they are not hit.
    I use Onsen UI v 2.10.5 and Angular.js v1.6.9
    What am I missing??
    Thanks
    Andy


  • administrators

    I’m not that familiar with the AngularJS compilation process, but the short answer is that the code in the controller is run before the onsLazyRepeat directive is compiled. When onsLazyRepeat is compiled, it exposes the refresh method so any code in the controller that runs immediately won’t be able to use refresh.

    I think the solution is to check when the EventManager.EVT_ALL_ITEMS_FETCHED event is firing - it must be before compilation has happened.

    Let me know if this isn’t enough information to solve the problem and I will look into the compilation process in more detail.



  • The refesh method is not used immediately but only when the data is loaded from the server which takes at least a couple of seconds
    Also I made a test where I just basically do exactly as in the sample i.e set the item count to some number, i.e 100, and in configurItemScope just do

    itemScope.item = "item" + index;
    

    Still the list is empty.
    Perhaps it’s some library that I’m missing? Or version incompatibility?
    Thanks
    Andy


  • administrators

    Hmmm that’s strange your test isn’t working. Can you try inserting the code exactly from the playground example and see if that works? https://onsen.io/playground/?framework=angular1&category=reference&module=lazy-repeat

    The only thing I can think of right now is that your code uses $scope whereas the playground example is using Controller as controller to reference the scope. Either is fine but both can cause problems so it’s worth checking they’re not accidentally both getting used somewhere.



  • No luck
    SImplified my code as much as possible. It looks like this now
    lazylist.html

    <ons-page ng-controller="ListController as list">
      <ons-toolbar>
        <div class="center">Lists</div>
        <div class="right">
          <ons-toolbar-button ng-click="list.doRefresh()">Refresh</ons-toolbar-button>
        </div>
      </ons-toolbar>
    
      <ons-list>
        <ons-list-item ons-lazy-repeat="list.delegate">{{ item }}</ons-list-item>
      </ons-list>
    </ons-page>
    

    The listcontroller.js

    angular.module('MyApp')
            .controller('ListController', function() {
    		    this.delegate = {
    		      configureItemScope: function(index, itemScope) {
    		        itemScope.item = 'Item ' + index;
    		      },
    		      countItems: function() {
    		        return 10000;
    		      },
    		      calculateItemHeight: function() {
    		        return ons.platform.isAndroid() ? 48 : 44;
    		      }
    		    };
    		    
    		   this.doRefresh=function(){
    			   this.delegate.refresh();//fails because refresh is not defined
    		   }
            });
    

    The only remaining difference between the sample and my code is the way onsen framework is initialized
    The sample uses

    ons.bootstrap()
      .controller('ListController', function() .....
    

    whereas my code uses

    angular.module('MyApp')
            .controller('ListController', function()....
    

    Could this be the problem?
    My app main module is defined in another file as follows

    (function () {
       'use strict';    
        var MyApp= angular.module('MyApp', ['onsen','ngCordovaOauth','rzModule', 'swipe'])
        .run(run); 
        run.$inject = ['$rootScope'];
      function run($rootScope) {
        	//app init
        }
        ons.ready(function() {
           // init plugins
        });
    })();
    

  • administrators

    From the code you provided, I can’t see what would be causing the problem.

    Do the list items themselves show up? (i.e. you get ‘Item 1’, ‘Item 2’, ‘Item 3’, not ‘{{ item }}’). If the list items don’t show up it’s probably because Onsen isn’t loaded properly or you have a typo somewhere.

    I don’t think it’s an Onsen version problem because I tried 2.10.1, 2.10.5 and 2.10.6 and they all worked for me.

    I also don’t think it’s caused by using angular.module instead of ons.bootstrap because I got it working fine with angular.module.

    There are a few other things you might be able to try:

    1. If it’s an open source project, put the project on GitHub and I’ll clone it and take a look at it.
    2. If it’s not an open source project but you don’t mind sharing some of the code, make the smallest possible working example and put it on GitHub.
    3. If it’s a Monaca project, contact Monaca support. You’ll need a paid plan but they’ll clone your project and figure out why it’s not working.


  • This is not an open source project .
    One thing that I’m suspicious of is the way the project is set up.
    It started as a Monaca project online IDE but then was copied locally and development continued. So the project index.html file does not inclde onsenui.js,angular.js etc. but instead includes loader.js
    However all other framework elements work just fine. The project uses ons-list, ons-tabbar, ons-navigator, ons-modal, etc and everything works,lazy-repeat is the only one thing that does not.
    Perhaps I neeed to revisit the way the project is organized ,get rid of the loader.js and use standard onsenui.js, angular.js and whatever else may be needed.
    Can you point me to a sample Onsen Angular JS skeleton project?
    Thanks
    Andy



  • @heel_curve5, in Local Kit, create a new project and select the type you want.

    0_1547150846303_71c93f47-756f-470f-aec0-c885118c0436-image.png



  • Thank you so much for pointing me to that tool. I was able to get the lazy list to work - created a skeleton Angular JS project,added the lazy load sample code to it and it worked!
    However here is another problem.
    It only works if the app is bootstrapped with my app=ons.bootstrap()…etc etc, like in the sample. My app is structured differently. I have a main module that is defined like this

    main-module.js

    (function () {
    'use strict';  
    var MyApp= angular.module('SmartConApp', ['onsen,'ngCordovaOauth','rzModule', 'swipe'])
    .run(run);
        run.$inject = ['$rootScope']; 	
    
        function run($rootScope, {
        	LogIt("APP MAIN");
        	// app initialization
        }
        ons.ready(function() {	
            LogIt("Onsen UI is ready!"); 
            // init plugins
        });
    })();
    

    The problem is that ons-ready is never called and neither is the run function
    Any ideas?
    Thank you so much for help


  • administrators

    It might be that you don’t have ng-app defined in your HTML. That was one thing that tripped me up when I tried to convert the example to use angular.module instead of ons.bootstrap.



  • @emccorson said in lazy-repeat refresh method is undefined:

    app

    Aha!
    That was it! Now it works
    Thank you all very much for help!
    Andy