2017-09-04 10 views
1

私はAngularJSにかなり新しいと私は20件の記事を取得し、作成したユーザーの 名と一緒にページ上に表示するためにAPIを1.Using要件複数のAPI呼び出しが

と運動の下に練習しています投稿してページに表示します。 この練習問題では、私はhttps://jsonplaceholder.typicode.com/をデータソースとして使用しています。 私はhttps://jsonplaceholder.typicode.com/users/userId(私は、ユーザー名を取得する必要が上記のユーザIDに基づいて、その中にユーザーIDを持っている20枚のポスト(https://jsonplaceholder.typicode.com/posts

  • のリストを取得するには、同じコントローラで2つのAPI呼び出し

    1. を行う必要があります) 私の仕事はplnkrで完了しました。投稿は表示できますがユーザー名は表示できません。

      Script.js

      var app = angular.module('myApp', []); 
      app.controller('myCtrl', function($scope, $http) { 
          $http.get("https://jsonplaceholder.typicode.com/posts").then(function(response) { 
           $scope.data = response.data; 
           var postList = []; 
           for (var i = 0; i < 20; i++) { 
            var display = { 
             UserName: $http.get("https://jsonplaceholder.typicode.com/users/" + $scope.data[i].userId).then(function(response) { 
              $scope.user = response.data; 
             }), 
             Post: $scope.data[i].title 
            } 
            postList.push(display); 
           } 
           $scope.list = postList; 
          }); 
      }); 
      

      Index.htmlと

      <div ng-repeat="x in list"> 
          Post:{{ x.Post }} 
          UserName:{{x.UserName}} 
      </div> 
      
  • +0

    plunkerリンクがあるが解消されたときにユーザーオブジェクトにユーザー名を追加し、それはスコープリストにプッシュするだろうか? –

    答えて

    1

    私は、この領域が間違っていると信じて:

    .then(function(response) { 
        $scope.data = response.data; 
        var postList = []; 
        for (var i = 0; i < 20; i++) { 
    
        var display = { 
         UserName: $http.get("https://jsonplaceholder.typicode.com/users/"+$scope.data[i].userId).then(function(response){ 
         $scope.user = response.data; 
         }), 
         Post: $scope.data[i].title 
        } 
        postList.push(display); 
        } 
        $scope.list = postList; 
    }); 
    

    Promise objectUserNameプロパティに格納し、予期しない結果が発生しました。

    .then(function(response) { 
        $scope.data = response.data; 
        var postList = []; 
    
        for (var i = 0; i < 20; i++) { 
    
        $http.get("https://jsonplaceholder.typicode.com/users/"+$scope.data[i].userId).then(function(response){ 
         $scope.user = response.data; 
    
         var display = { 
         UserName: "", 
         Post: $scope.data[i].title 
         }; 
    
         $scope.list.push(display); 
        }); 
        } 
    
        $scope.list = postList; 
    }); 
    

    をあなたがこれを実装したら、あなたは新しい問題が発生します:あなたがループ内で$http.get()と呼ばれ、実際に変数を使用するので

    を要求が完了した後に、これはpostListを割り当てる修正する

    i.then().then()の値を実行するとの値はi = 20 | data.lengthであり、最終的な形式は.then()となります。

    この問題を克服するために、私が知っている最良の方法は、それを表示する前に最初の全体のデータをフォーマットすることです。我々は、データがビューでそれを表示する前に完了していることを確信している、このように

    $http.get("https://jsonplaceholder.typicode.com/posts") 
        .then(function(response) 
        { 
        var data  = response.data; 
        var postList = []; 
        // this will check if formatting is done. 
        var cleared = 0; 
    
        // create a function that checks if data mapping is done. 
        var allClear = function() { 
         if (postList.length == cleared) 
         { 
         // display the formatted data 
         $scope.list = postList; 
         } 
        }; 
    
        for (var i = 0; i < data.length; i++) 
        { 
         // create a object that stores the necessary data; 
         var obj = { 
         // the ID will be needed to store name; 
         ID: data[i].userId, 
         Post: data[i].title, 
         UserName: "" 
         }; 
         var url = "https://jsonplaceholder.typicode.com/users/" + obj.userId; 
    
         $http.get(url).then(function(response) 
         { 
         // find its entry in the array and add UserName; 
         postList.forEach(function (item) 
         { 
          if (item.ID == response.userId) 
          { 
          // just add the correct key, but I will assume it is `userName` 
          item.UserName = response.userName; 
          // break the loop 
          return item; 
          } 
         }); 
    
         // increment cleared 
         cleared++; 
         // call allClear 
         allClear(); 
         }); 
    
         postList.push(obj); 
        } 
        } 
    ); 
    

    このソリューションは、元のオブジェクトに結果をマッピングするためにa loopが含まれているとして、我々は実際にそれが少し速く作るためにオブジェクトとしてpostListを変更することができます。このセクションの

    // var postList = []; 
    var postList = {}; 
    
    // instead of pushing we will use the ID as key 
    // postList.push(obj); 
    postList[obj.ID] = obj; 
    

    などを:

    $http.get(url).then(function(response) 
        { 
        // instead of looking for the item in .forEach 
        postList[response.userId].userName = response.userName; 
        // increment cleared 
        cleared++; 
        // call allClear 
        allClear(); 
        }); 
    

    希望するものがあります。

    +0

    ソリューションをありがとう、期待どおりに動作しました。@ masterpreenz – 62071072SP

    1

    簡単な解決策は、約束が

    var app = angular.module('myApp', []); 
    app.controller('myCtrl', function($scope, $http) { 
        $http.get("https://jsonplaceholder.typicode.com/posts").then(function(response) { 
         $scope.data = response.data; 
         $scope.list = []; 
         for (var i = 0; i < 20; i++) { 
    
          $http.get("https://jsonplaceholder.typicode.com/users/" + $scope.data[i].userId) 
           .then(function(response) { 
            var user = { 
             UserName: response.data.username, 
             Post: $scope.data[i].title 
            } 
            $scope.list.push(user); 
           }); 
         } 
        }); 
    }); 
    
    関連する問題