Debuginfo

思考とアウトプット

Instagram APIでPaginationを実現する

Instagram APIでユーザフィードはデフォルトで20しか返ってきません。Countパラメータで変更可能ですが、自分が確認したところ、30ぐらいが上限のようです。なのでユーザが見ているときに、"もっと見る"のようなボタンを容易して次を見させるのがよさそうです。

方針は、

  1. /users/user-id/media/recent に投げる
  2. レスポンスのデータ処理
  3. 最後まで読み込んだらボタンを消す

投げるのはサーバ側。max_idはクライアントで持つことがポイントですかね。

1. /users/user-id/media/recent に投げる

/users/self/feedはフォロワーの投稿も入ってしまうので、今回の用途ではこっちは却下。countは30で投げる。処理はサーバ側で。 細かいところは省略するが、以下の感じで投げる。( PerlMojo::UserAgentを利用) max_idなしで投げると最新の写真から30個ぐらい返ってくる。

sub get_my_feed {
    my ($self, $access_token, $user_id, $max_id) = @_;
    my $tx;
    if (defined $max_id){
        $tx = $self->ua->get("https://api.instagram.com/v1/users/$user_id/media/recent?access_token=${access_token}&count=30&max_id=$max_id");
    }else { 
        $tx = $self->ua->get("https://api.instagram.com/v1/users/$user_id/media/recent?access_token=${access_token}&count=30");
    }
    return $tx->res->json;
}

2. レスポンスのデータ処理

response.pagination.next_max_idに次のmax_idが入ってくるのでこれを次から使う。max_idはクライアント側で持ってて、GETのパラメタでサーバ側に投げる。下記、AngularJSのコード(リファクタリング前で汚いですが、、)

$scope.data = new Array();  
    $scope.showLoadNext = true;
    var max_id;  

    $scope.loadNext = function(){
        $http({method: 'GET', url: '/api/instagram/feed', params: {max_id: max_id} }).
        success(function(res, status, headers, config) { 
                                                         
            if(typeof res.pagination.next_url === "undefined"){
                $scope.showLoadNext = false;             
            }                                            
            $scope.data = $scope.data.concat(res.data);
            max_id = res.pagination.next_max_id;
        }).                             
        error(function(data, status, headers, config) {
            // do nothing               
        });                             
    }; 
    $scope.loadNext();  

3. 全部表示したらボタンを消す

もっと見続けると最後までいって、next_max_idがundefinedになる。上記のコードのtypeof のラインがそう。AngularJSですが、Viewでng-showを使ってハンドルする。

<button ng-show="showLoadNext" class="btn btn-info btn-lg" ng-click="loadNext()">More</button>

時間があったら、無限スクロール的に下に行ったら自動的にロードするようにしたいな。