2016-10-27 8 views
2

私が取り組んでいるプロジェクトでは、REST APIからデータを要求し、解析するための2つの反応メソッドを記述しました。しかし、解析されたデータを保持するはずの配列は、常に空を返します。なぜこのことが起こっているのか分かりません。どんな助けもありがとうございます。Reactコンポーネントメソッドが空の配列を返します

は、データをフェッチし、解析するための方法に反応:レストAPIからのデータの

getData(){ 
    const { url, queries } = this.state; 
    let data_arr = []; 

    for (let q = 0; q < queries.length; ++q){ 
     let query = queries[q], 
     post_query = { 
      full_name: query.name, 
      date_start: query.startdate, 
      date_end: query.enddate 
     }; 

     axios.post(url, post_query).then((response) => data_arr.push(response.data)); 
    } 

    return this.setState({data: data_arr}); 
} 
parseData(){ 
    const { data } = this.state; 
    let dataParsed = []; 

    for (let d = 0; d < data.length; ++d){ 
     const provider_entries = data[d]; 
     let provider_table = { 
      name: provider_entries[0].full_name, 
      size: 6, 
      table: { 
       rows: [], 
       columns: [ 
        {key: 'Date', type: 'date', filterable: true, sortable: true}, 
        {key: 'Charges', type:'number', filterable:true, sortable: true}, 
        {key: 'Payments', type: 'number', filterable: true, sortable: true}, 
        {key: 'Appointments'} 
       ] 
      } 
     }; 

     for (let p = 0; p < provider_entries.length; ++p){ 
      const provider_row = provider_entries[p], 
      id_val = p++; 
      let row = { 
       id: id_val, 
       Date: provider_row.date, 
       Medical: provider_row.charges.medical, 
       Cosmetic: provider_row.charges.cosmetic, 
       Total: provider_row.charges.total, 
       Payments: provider_row.payments, 
       Appointments: provider_row.appointments 
      }; 

      provider_table.table.rows.push(row); 
     } 

     dataParsed.push(provider_table); 
    } 

    return this.setState({ data_formatted: dataParsed }); 

} 
componentDidMount(){ 
    this.datafetch = setInterval(() => { 
     this.getData(); 
     this.parseData(); 

     const { data, data_formatted } = this.state; 

     console.log(data, data_formatted); 
    }, 5000); 
} 

例:

[ 
[ 
    { 
    first_name: "First Name Here...", 
    last_name: "Last Name Here...", 
    full_name: "Full Name Here", 
    date: "2016-01-17", 
    charges: { 
     cosmetic: 25000.00, 
     medical: 25000.00, 
     total: 50000.00 
    }, 
    payments: 75000.00, 
    appointments: 99, 
    pk: 5 
    }, 
    { 
    first_name: "First Name Here...", 
    last_name: "Last Name Here...", 
    full_name: "Full Name Here", 
    date: "2016-01-24", 
    charges: { 
     cosmetic: 25000.00, 
     medical: 25000.00, 
     total: 50000.00 
    }, 
    payments: 75000.00, 
    appointments: 99, 
    pk: 5 
    }, 
], 
[ 
    { 
    first_name: "First Name Here...", 
    last_name: "Last Name Here...", 
    full_name: "Full Name Here", 
    date: "2016-01-17", 
    charges: { 
     cosmetic: 25000.00, 
     medical: 25000.00, 
     total: 50000.00 
    }, 
    payments: 75000.00, 
    appointments: 99, 
    pk: 5 
    }, 
    { 
    first_name: "First Name Here...", 
    last_name: "Last Name Here...", 
    full_name: "Full Name Here", 
    date: "2016-01-24", 
    charges: { 
     cosmetic: 25000.00, 
     medical: 25000.00, 
     total: 50000.00 
    }, 
    payments: 75000, 
    appointments: 99, 
    pk: 5 
    }, 
] 
]; 

答えて

1

あなたは持っている問題は、あなたが非同期ですAJAX呼び出しを行うと状態を設定していることです直後の。ワークフローは次のとおりです。Axisでapi呼び出しを行い、データが戻った後に実行される.then関数に連鎖すると、そのデータが配列にプッシュされます。実際のjavascriptワークフローは次のようなものです:応答が返ってくるのを待つのではなく、ajax呼び出しを行い、javascriptを実行し続け、setstate関数を実行します。 setState関数が実行された時点で、応答が戻ってこないため、データ配列はまだ空です。

もし私がaxios.allを使って調べると、ajax呼び出しの配列がmakeに渡され、.then関数をチェーンすることができ、すべてのapi呼び出しが実行されると実行されます。その時点で、すべてのデータをデータ配列にプッシュし、同じ.thenブロック内でsetStateをプッシュできます。これにより、データが実際に戻ったときに状態が更新されます。

あなたはそれが一度に複数のAPI呼び出しを行う方法を説明し、この記事http://codeheaven.io/how-to-use-axios-as-your-http-client/#performing-multiple-requests-simultaneouslyをチェックすると

のようなもの、私はそれを再確認したいので、テストする機会を持っていませんでした動作するはずです以下が、それはやるべき私が話していること

getData(){ 
    const { url, queries } = this.state; 
    let data_arr = []; 

    // map over queries, create array of axios promises 
    const axiosQueries = queries.map(function(query) { 
     let post_query = { 
      full_name: query.name, 
      date_start: query.startdate, 
      date_end: query.enddate 
     }; 
     return axios.post(url, post_query) 
    }); 
    // set self to be equal to react component 
    var self = this; 

    // chain all axios promises and then give the results back as an array containing each request 
    axios.all(axiosQueries).then(function(results){ 

    // go through each result and push it into data array 
    results.forEach(function(response) { 
     data_arr.push(response.data) 
    }) 

    // once all data is processed set state to data array. 
    return self.setState({data: data_arr}); 

    }) 

} 
+0

私がこれについて持っている1つの質問は、 'axios.spread'の引数にどのように対処できるのでしょうか?メソッドが受け取るクエリの量は動的です。 Axiosの 'spread'メソッドの引数を動的に変更する方法はありますか? – TechEmperor95

+0

あなたが行っている呼び出しを正確に知っているときは、 'axios.spread'を使うべきです。私が自分自身を投稿したコードを見ると、 'axthen.spread'ではなく' .then(function(results) ')を実行して、結果を各約束の戻り値の配列にすることになります。 – finalfreq

+0

恐ろしいです!あなたがes6を使っているならば答えを加えました。 'axios.all(axiosQueries).then((results)=> {'そして矢印関数は 'this'をバインドします反応する成分。 – finalfreq

関連する問題