2016-11-18 8 views
1

私のプロジェクトは、反応して、Reduxの、Reduxの-佐賀に基づいES6と私は、このAPIからデータを取得しようとしている。複数のページにデータをフェッチする方法は?

http://api.dhsprogram.com/rest/dhs/data/BD,2000,2004,2007?&returnFields=CharacteristicLabel,Indicator,IndicatorId,Value&f=json

あなたが見ることができるように、この特定のAPI呼び出しが限度とのデータを示しています1ページあたり100データが40ページに分散されます。

この回答によれば、 http://userforum.dhsprogram.com/index.php?t=msg&th=2086&goto=9591&S=Google ページあたり最大3000dataに制限を拡張できます。

しかし、いくつかのケースでは私はこのようにそれをやって、すべての私のデータを受信しないだろうということの限界超えてAPIの呼び出しだろう:

export function fetchMetaData(countryCode: string, surveyYears: string) { 
return (fetch('http://api.dhsprogram.com/rest/dhs/data/' + countryCode + ',' + surveyYears + '?returnFields=CharacteristicLabel,Indicator,IndicatorId,Value&f=json') 
    .then(response => response.json()) 
    .then(json => json.Data.map(survey => survey))) 
} 

だから私の質問ですが、私はデータの総ページを知っているので、このAPIからすべてのデータを取得する最善の方法は何ですか。フォーラムリンクの答えは、APIをループすることを提案しています。しかし、私はこれを行うための正しい構文の使用法を見つけることができません。

私の考えは、総ページ数を得るために1回のAPI呼び出しを行うことです。これをredux + redux-sagaを使って状態に保存します。次に、新しい要求をパラメータとして合計ページを送信し、この総ページ数をフェッチします。これを行うことで、各反復ごとにデータを保存する構文を理解することはできません。

+0

いくつか質問があります。1.なぜあなたはreduxストアの総ページ数を保存する必要がありますか?おそらく、(非同期フェッチをいくつか使用して)すべてのデータを1つのアクションにフェッチすることをカプセル化するのは難しいでしょう。 2.あなたは「...開始ページをパラメータとして送信しています...」という意味でしょうか? 3.具体的にあなたの問題は何ですか、これまで何を試しましたか?配列を反復する?集約?いくつかの非同期呼び出しや約束を扱う? – matthias

+0

1.レデックス・ストアに総ページ数を格納することは、私自身の問題に対する示唆に過ぎず、提案するものはより論理的に聞こえる。 2.修正する。 3.私がこれまで行ってきたことは、redux-sagaを使って非同期フェッチを処理することでした。私のコンポーネントがアクションをディスパッチすることによってデータを要求すると、サガのウォッチャーは上記の関数からアクションとリクエストデータを受け取ります。私が受け取るのは、私がアクション本体に保存した1ページのデータです。それを私のレデューサーに追加します。私の問題は、上記の関数を使ってすべてのページからすべてのデータを取得できないということです。これを行うにはスマートな方法がありますか? @matthias –

+0

さて、私たちはこの点に近づいています。私はredux-sagaを使ったことは一度もなく、このライブラリがこれを解決するための専用の優先的な方法を提供しているかどうかはわかりません。しかし、これは、プロンプト(または非同期/待機)と配列/オブジェクトの構築/マッピングを扱う関数を使用して、典型的な方法で問題を解決するのを止めてはならないとは思わない。もしあなたが正しいとすれば、1つのAPIへのいくつかの非同期呼び出しを実行し、収集したデータを集計し、ストア/レデューサーに渡して新しい状態を作成する方法を探しています。私は尋ねるかもしれません:あなたはJavaScriptに一般的にどれくらい精通していますか – matthias

答えて

4

考えられる解決策は、最初にページ数を取得してから、適切な数のAPI呼び出しを行い、各呼び出しから約束を配列にプッシュすることです。その後、すべての約束が解決するのを待って、返されたデータで何かを行います。

function fetchMetaData() { 
    let pagesRequired = 0; 

    fetch('apiUrlToGetPageNumber') 
    .then(resp = > { 
     const apiPromises = []; 
     pagesRequired = resp.data.pagesRequired; 

     for (let i=pagesRequired; i>0;i--) { 
      apiPromises.push(fetch('apiUrlToSpecificPage?page = ' + i)); 
     } 

     Promise.all(apiPromises) 
     .then(responses => { 
      const processedResponses = []; 
      responses.map(response => { 
       processedResponses.push(response); 
      } 

      // do something with processedResponses here 
     }); 
    } 
} 
+0

ありがとうございます!(私は答えをupvotedしかし、私は15rep未満)。ただし、processedResponsesに.reduceを使用すると、この関数はprevが定義されていることを思い出すことができます。しかし、私は考えを得るので、私はそれを把握しようとします! –

+0

削減のポイントは、私は動作するものに編集します。 –

+0

=) –

0

async/awaitを使用する別の解決策があります。これの美しさは、total_pagesが動的なので、リクエストを処理している間にカウントが増えれば、すべて取得できることです。

async function fetchMetaData() { 
    let allData = []; 
    let morePagesAvailable = true; 
    let currentPage = 0; 

    while(morePagesAvailable) { 
    currentPage++; 
    const response = await fetch(`http://api.dhsprogram.com/rest/dhs/data?page=${currentPage}`) 
    let { data, total_pages } = await response.json(); 
    data.forEach(e => allData.unshift(e)); 
    morePagesAvailable = currentPage < total_pages; 
    } 

    return allData; 
} 
関連する問題