javascript - react : Trying to set an API JSON response to state object and pass it to component for mapping and rendering

标签 javascript reactjs axios

我有一个组件,在 this.setState: { } 中设置了一个名为 customers: [] 的空数组。加载时,组件会触发对 API 的 POST 调用,该调用返回一个 XHR 名称为 CustomerOffers 的 JSON 对象。我有逻辑来迭代数组并将 JSON 对象的所有部分映射到 UI,但每次加载应用程序时,我都会收到一条错误消息,指出 TypeError: this.state.customers.map is not一个函数,但是当我使用客户数组内的虚拟数据测试它时,所有内容都正确呈现。我使用 console.log 语句打印来自 API 的返回响应,它显示为未定义,这让我相信在返回过程中的某个地方应用程序没有获取数据。我在下面包含了我的代码,对此的任何帮助都将是巨大的!

react

import React, { Component } from 'react';
import './Button.css';
import Grid from '@material-ui/core/Grid';
import axios from 'axios';

class UsersList extends Component {


  constructor(){
        super();
        // this.selectCard  = this.selectCard.bind(this);
        // Define data model object and cardActive 
        this.state = {

            cardActive: null,

            dataModel: {
              offerName: null,
              customerId: null
            },

            SessionId: null,

            customers: []
        }



        // this.updateOffer = offerID => {};

        this.submitData = () => {
          let temporalDataModel = this.state.dataModel;

          temporalDataModel.SessionId = this.state.SessionId;

          console.log(
            "Transmitting data...NOW",
            temporalDataModel
          );

          this.setState(
            {
              dataModel: temporalDataModel
            },
            () => {
              let postUrl = "https://myAPI.com";
              axios
                .post(postUrl, this.state.dataModel)
                .then(response => {
                  console.log(response);
                })
                .catch(err => {
                  console.error(err);
                });
            }
          );
        };

        this.selectCard = obj => {
          let temporalDataModel = this.state.dataModel;

        //   console.log("paramenters", obj);
        //   console.log("currentState", temporalDataModel);

          this.state.customers.forEach(c => {
            if (c.CustomerId === obj.customerId) {
              c.Offers.forEach(off => {
                if (off.OfferId === obj.offerId) {
                  console.log("offer", off);
                  temporalDataModel.customerId = obj.customerId;
                  temporalDataModel.offerName = off.Name;
                  temporalDataModel.offerId = off.OfferId;
                  temporalDataModel.products = off.Products;
                  temporalDataModel.sessionId = obj.SessionId;
                }
              });
            }
          });

          console.log("data updated", temporalDataModel);

          this.setState({ cardActive: obj.offerId, SessionId: obj.SessionId,  });
        };
    }


    getCustomerOffers(){
      var search = window.location.search;
      var params = new URLSearchParams(search);
      var customerId = params.get('CUSTOMERID');
      var sessionId = params.get('SESSIONID');
      var data = "{'CustomerId':'1','SessionId':'9636','IsExisting':'true'}";

      var requestOffers = { 
        method: 'post',
        url: 'https://myAPI.com',
        data: "{'CustomerId':'" + customerId + "','SessionId':'" + sessionId + "'}"
    };


          axios.post('https://myAPI.com',
               "{'CustomerId':'" + customerId + "','SessionId':'" + sessionId + "'}")
           .then((res) => {
               console.log("RESPONSE RECEIVED: ", res);
               this.setState({
                   customers: res.data
               });
               console.log("Customer: ", this.state.customers.CustomerId);
           })
           .catch((err) => {
               console.log("AXIOS ERROR: ", err);
           });

    }


    componentDidMount(){
      this.getCustomerOffers();

    }


    // selectCard(offerId) {   
    //     this.setState({ cardActive: offerId });
    //   }


    render (){
        return (
          this.state.customers != null && 
          <div>
          {this.state.customers.map((customer, index) => {
              return  <div key={index + customer.CustomerId}>

                              <h3 >Name: {customer.LastName}, {customer.FirstName}</h3>
                              <h3 >Customer ID: {customer.CustomerId}</h3>
                              <h3 >
                              Address: 
                              <br></br>
                              {customer.Address.Address1}
                              <br></br>
                              {customer.Address.City}, {customer.Address.State} {customer.Address.Zip} 
                              </h3>
                              <br></br>
                              <h2>Available Offers</h2>
                              <Grid container spacing={24} justify="center"> 
                              {customer.Offers.map((Offer,index) => {
                                  return <div key={index + Offer.OfferId} onClick={() => {
                                      const obj = {
                                        offerId: Offer.OfferId,
                                        customerId: customer.CustomerId,
                                      };
                                      console.log("Offer ID:",Offer.OfferId, ",Customer ID:",customer.CustomerId,",Offer Name:", Offer.OfferName, ",Session ID:", customer.SessionId);
                                      this.selectCard(obj);
                                    }}>
                                          <Grid item xs={12}>
                                          <div className={Offer.OfferId === this.state.cardActive ? "cardActive" : "card"}>
                                              <div className="container">
                                                  <h5><b>{Offer.OfferId}</b></h5> 
                                                  <h2>{Offer.Name}</h2>
                                                  {Offer.Products.map((Product, index) => {
                                                      return <div key={index + Product.ProductId}>
                                                              <p>+ {Product.ProductName}</p>
                                                            </div>

                                                  })}
                                                  <h3>{Offer.Price}</h3> 
                                              </div>
                                          </div>
                                          </Grid>

                                      </div>
                              })}

                              </Grid>

                      </div>

          })}

          <button className="navbuttonSelected" disabled={!this.state.cardActive} onClick={this.submitData}>Submit</button>

      </div>
        )

    }
}

export default UsersList

最佳答案

我认为您没有像异步请求那样使用 Axios(或 try 和 catch)。

Try 和 Catch block 只能用于同步代码块。当您进行 api 调用时,它是异步的(即需要随机的时间才能完成)。要捕获异步 block 上的错误,通常会使用附加到 Promise 的 .catch(handlerFunction) 。

应该是这样的:

axios.post(myurl, mydata).then(res => console.log(res))
   .catch(e => console.log(e))

因此 getOffer 可能会被重写:

const getOffers = (trequest) => {
    return axios(trequest)
      .catch(e => console.log(e) );
}

要获得结果,您需要执行以下操作:

getOffers('/getmyoffers').then(results => console.log(results) )

编辑 - 要更新客户状态,您可以执行以下操作:

getOffers('/getmyoffers').then(results => this.setState({customers:results.data} )

关于javascript - react : Trying to set an API JSON response to state object and pass it to component for mapping and rendering,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55109926/

相关文章:

javascript - 如何使用 asp.net web 表单在 javascript 中使用 vb 变量?

javascript - 将 componentDidMount 添加到 React 组件会导致语法错误

node.js - 使用axios上传图片的问题

javascript - 检查 Axios Promise catch block VueJs 中的 HTTP 状态代码

javascript - Istanbul 尔纽约将包含测试文件

javascript - 在 javascript 中使用搜索并替换为正则表达式

c# - gridview 中的标签更改但更改不回发

reactjs - REACT JEST 错误无法从 'jest-matchers' 找到模块 'jest-expect.js'

javascript - 以日期为键的映射无法正确检索项目

javascript - 使用es6promise顺序进行远程调用