3

I'm trying to create a infinite scroll feature in my application but it feels a bit abstract. I want to use ui-scroll and this fiddle shows a simple example of how it works.

I've read the readme and looked through some examples also I've integrated the example in my project and got it working, but I can't figure out on how to combine this with data from my own database.

I have a database table called movies. The movies have a few values such as title, release_date, image_url

How would I insert that data into the $scope.movieDataSource so I can use it in my view?

$http.get(('/movies.json'), {
    cache: true
  })
  .success(function(data, status, headers, config) {
    if (status == 200) {
      $scope.userMovies = data;
    } else {
      console.error('Error happened while getting the user list.')
    }
    $scope.movieDataSource = {
      get: function(index, count, callback) {
        var i, items = [$scope.userMovies], item;
        var min = 1;
        var max = 1000;

        for (i = index; i < index + count; i++) {
          if (i < min || i > max) {
            continue;
          }
          item = {
            title: $scope.userMovies.title,
            imageURL: $scope.userMovies.poster_path
          };
          items.push(item);
        }
        callback(items);
      }
    }
  });

I've tried to create an example of what I'm trying to get at. I use a http.get to fill my userMovies scope with records from my database and I want to use those records as items in the movieDataSource.

But when I visit the page I that ui-scroll does add results in the container, but it does not show content.

<div class="imageCell ng-scope" ui-scroll="item in movieDataSource">
  <img title="">
</div>

If I console.log("movieDataSource" + $scope.movieDataSource) it shows me movieDataSource[object Object].

15
  • the code you posted here and the fiddle you provided seem to work correctly. What is the issue you are trying to work out here? does setting item equal to your data not serve your purpose? Commented Oct 12, 2015 at 14:30
  • @Claies I'm trying to figure out how I can use data from my own database as items in the movieDataSource so I can show those records in my view instead of the numbers that are generated now. Commented Oct 12, 2015 at 14:33
  • I'm still not clear on what data you have, but it seems like the only thing you would have to change is the item = assignment call. Commented Oct 12, 2015 at 14:36
  • something like item = yourData[i]; if yourData was an array you already have.... Commented Oct 12, 2015 at 14:38
  • I have a database table called movies inside that table are 1000 records, each record has a title, release_date. I want to display that data in my view through the movieDataSource Commented Oct 12, 2015 at 14:49

2 Answers 2

8

You are making this more complex than necessary. The uiScroll directive is a replacement for ngRepeat, which takes a Data Source with 3 properties:

  • index indicates the first data row requested
  • count indicates number of data rows requested
  • success function to call when the data are retrieved. The implementation of the service has to call this function when the data are retrieved and pass it an array of the items retrieved. If no items are retrieved, an empty array has to be passed.

in your case, you have an array of items. Each time the index or count changes, the success fires, and this function should return a subset of your array from index to index + count. There are multiple ways to accomplish this. The example you posted uses a for loop to iteratively push items into the array. You could also use the Array.slice() method.

Option 1:

 $scope.movieDataSource = {

   get: function(index, count, callback) {
     var i, items = [], item;

     for (i = index; i < index + count; i++) {
       item = $scope.userMovies[i];
       items.push(item);
     };

     callback(items);
   }
 }

Option 2:

 $scope.movieDataSource = {

   get: function(index, count, callback) {
     var items = $scope.userMovies.slice(index, index + count);
     callback(items);
   }
 }

As for your HTML, it should be identical to if you were using ng-repeat:

<div ui-scroll="item in movieDataSource">
  {{item.title}}
  <img title="{{item.title}}" ng-src="{{item.poster_path}}"></img>
</div>
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you for taking the time help me understand the issue. jsfiddle.net/q4xstonz/10 is pretty much what I wanted, except I just saw you can't filter or use orderBy since it's not Angular. It looks like I need to order the array in the controller. I always thought I could get by with my little JS knowledge, and I could when I was only using jQuery, but now I'm diving more and more in Angular it looks like I really need to get more knowledge of Javascript.
you won't be able to filter or order the movieDataSource because it is not bound to your entire array, it is only bound to the subset of the array that is currently visible. That's the way that directive works, it adds items to the DOM as you scroll, and removes items that go out of view, which means you don't have two way binding anymore, so yes, you would have to filter or order userMovies instead.
shouldn't callback(items); be enclosed within the get function?
@LukeHutton I don't really recall what I was doing in 2015 when I wrote that logic, but clearly I had both functions wrong; thanks for identifying my mistake.
0

Apparently ui-scroll calls the given object "movieDataSource" with an index and a count. It then expects the function to push all items between index and index + count in the returned array.

That means that you have to implement code that fetches the respective items from your DB (via REST or however you access your data) and insert the returned records in the items array.

1 Comment

I've updated the question with an example of how I think it might work, but it's not showing the needed result. Could you maybe give some feedback?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.