简体   繁体   中英

instagram feed with ionic framework infinite-scroll doesn't stop duplicates in repeater error

I'm trying to build an IOS and android app with Ionic Framework that has an Instagram Feed with the instagram api that shows all photos shared by hashtag (I'll use the hashtag chocolat has an example) and I wanted to implement pull to refresh and infinite scrolling, so basicaly I would have a button that once clicked opened a view with the instagram feed and pulled the first 10 results, pull to refresh would try to get newer results, then if the feed was scrolled down it would add the next set of results (older results). I've been searching and I've built something that isn't working quite as intended. I'm a newbie developer in ionic, angularjs and javascript so i decided to post my question here.

So here is my code:

The factory or service to get the instagram json by http:

app.factory('PhotoService', function($http){ 
  var BASE_URL = "https://api.instagram.com/v1/tags/chocolat/media/recent?access_token=+++"; 
  //access_token hidden for privacy reasons
  var items = [];
  var nextUrl = 0;

  return {
    GetFeed: function(){
      return $http.get(BASE_URL+'&count=10').then(function(response){
        items = response.data.data;
        nextUrl = response.data.pagination.next_url;

        return items;

        });
    },
    GetNewPhotos: function(){
      return $http.get(BASE_URL+'&count=2').then(function(response){
        items = response.data.data;

        return items;
      });
    },
    GetOldPhotos: function(){
      return $http.get(nextUrl).then(function(response){

        items = response.data.data;
        return items;
      });
    }
  }
});

The controller:

app.controller('CivrInstagramController', function($scope, $timeout, PhotoService) {
  $scope.items = [];
  $scope.newItems = [];

  PhotoService.GetFeed().then(function(items){
    $scope.items = items;
  });

  $scope.doRefresh = function() {
    if($scope.newItems.length > 0){
      $scope.items = $scope.newItems.concat($scope.items);

     //Stop the ion-refresher from spinning
     $scope.$broadcast('scroll.refreshComplete');

     $scope.newItems = [];
    } else {
      PhotoService.GetNewPhotos().then(function(items){
        $scope.items = items.concat($scope.items);

        //Stop the ion-refresher from spinning
        $scope.$broadcast('scroll.refreshComplete');
      });
    }
  };

  $scope.loadMore = function(){
    PhotoService.GetOldPhotos().then(function(items) {
      $scope.items = $scope.items.concat(items);

      $scope.$broadcast('scroll.infiniteScrollComplete');
    });
  };
});

The view:

<ion-view view-title="#Chocolat Photos!">
  <ion-content>
    <ion-refresher on-refresh="doRefresh()"></ion-refresher>
    <div class="list card" ng-repeat="item in items track by item.id">
      <div class="item item-avatar">
        <img ng-src="{{item.user.profile_picture}}" ng-  if="item.user.profile_picture.startsWith('https')">
        <h2>{{item.user.full_name}}</h2>
        <p><span am-time-ago="item.created_time" am-preprocess="unix"></span></p>
      </div>

      <div class="item item-body" >
        <img ng-src="{{item.images.low_resolution.url}}" ng-if="item.images.low_resolution.url.startsWith('https')">
        <p>
          {{item.caption.text}}
        </p>
      </div>

    </div>
    <ion-infinite-scroll on-infinite="loadMore()" distance="5%"></ion-infinite-  scroll>
  </ion-content>
</ion-view>

The PhotoService.GetFeed() is working well as it populates correctly the first 10 photos, however, when I try to infinite-scroll I get the error:

Error: [ngRepeat:dupes] Duplicates in a repeater are not allowed. Use 'track by' expression to specify unique keys.

I'm using track by item.id as you can see in the view, so i think this means im getting the same results over and over again with the PhotoService.GetOldPhotos() . as for the PhotoService.GetNewPhotos() it works when there is new data to display but it throws the same error of duplicates in a repeater when there is no new data to fetch (no new posts with #chocolat)

What am i doing wrong? can anyone give me some advice? Thanks in advance for your time! Here is a plnkr ++ link to my project where you can actually see it trying to work :\\

++ you might need to enable cross-origin resource sharing in your browser to see the feed working.

EDIT1 : ALMOST DONE!

So after some long hours and after some console.log()'s :p I was able to get a instagram feed by tag and make it work with ionic pull to refresh and ionic infinite scrolling (well 90% I guess) but I'm still with a problem with my code, because every time I scroll to the last set of items I can't stop infinite scroll nor loadMore() and they will try to load more data, because the last nextUrl is undefined but instagram-api accepts the &next_max_tag_id=undefined and gets me the most recent results again and this results in an error because there can be no duplicates in ng-repeat and I dont want to show the first results again.

I just need to stop loadMore and infinite-scroll when there are no more results, or if &next_max_tag_id=undefined, or if there are duplicates in both arrays (but I don't think this is recommended performance wise). So here is a plnkr with my project, thank you for your time!

I changed the tag to something with low results so you can actually see the error without getting tired of scrolling :p

We solved this separately, but I figured I'd post the answer here too. The main changes are

  1. Switch to JSONp to avoid CORS restraints
  2. Use instagram's min_tag_id and max_tag_id format
  3. Update the getOldPhotos() method to automatically return an empty array when there is no next_max_tag_id (Technically, it returns a different promise that's already resolved to an empty array.)
  4. Change $scope.loadMore() to check for an empty response and set a flag to kill the <ion-infinite-scroll>

See a full working copy here: http://plnkr.co/edit/LBW0pp?p=preview

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM