Search code examples
c#reactjsaxiosapi-design

Uncaught (in promise) TypeError: data.map is not a function (React using axios getting data from ASP.NET API)


I've created an API using ASP.NET, and I've got a Website running React. I'm wanting to display the data retrieve with a get request from the API to React using Axios. The website has an authentication method using two cookies. I can get the Axios to get data from https://jsonplaceholder.typicode.com/users, but when i use the same bit of code, then I get the error: Uncaught (in promise) TypeError: data.map is not a function.

I've tried as mentioned above to use a placeholder, and that works fine, but can't seem to get thedata from my API, which leads me to believe that the problem lies in the cookies. I've also tried a few Google searches, which returned that I should include withCredentials: true, but that doesn't do the trick.

Here is the function from my API:

public JsonResult YearlyManagersJSON(int year = 0)
{
    if (year < 2000 || year > DateTime.Today.Year)
        year = DateTime.Today.Year;

    var startDate = new DateTime(year, 1, 1);
    var endDate = new DateTime(year + 1, 1, 1);

    var bonds = this.getOverviewData(ReportType.BONDS, startDate, endDate);
    var bondsSum = bonds.Sum(m => m.Aggregate);

    var viewData = new TopLeadManagerViewData
        {
            Title = String.Format("Top Managers in {0}", startDate.Year),
            Currency = SiteHelper.getCurrencyToUse(),
            Bonds = Enumerable.Select(bonds, m => new ManagerSummary()
                {
                    NumberOfIssues = (int)m.Aggregate2,
                    TotalAmount = m.Aggregate * 1000000,
                    Name = m.Group.ToString(),
                    Share = 100.0m * m.Aggregate / bondsSum
                }),
        };

        return this.Json(viewData, JsonRequestBehavior.AllowGet);
}

This returns a JSON, which i have checked using Postman. Then i try to access the data using axios.

state = {
    yearlyBonds: []
}

componentDidMount() {
    axios.get(
        'http://localhost/Stamdata.Web/LeagueTable/YearlyManagersJSON',
        { withCredentials: true }
    )
    .then(res => {
        const yearlyBonds = res.data;
        this.setState({ yearlyBonds });
    })
}

render() {
    return (
        // Tags removed for simplicity
        <ListTable data={this.state.yearlyBonds.Bonds} />

The data is then passed down into the component

function ListTable(props) {
        const { classes, header, data } = props;
        return(
            // Tags removed for simplicity
                        <TableBody>
                            {data.map((x, i) => {
                                return(
                                    <TableRow key={i}>
                                        <TableCell scope="row">{x.Name}</TableCell>
                                        <TableCell scope="row">{x.TotalAmount}</TableCell>
                                        <TableCell scope="row">{x.Share}</TableCell>
                                        <TableCell scope="row">{x.NumberOfIssues}</TableCell>
                                    </TableRow>
                                )
                            })}
                        </TableBody>

So, this returns the error

"Uncaught (in promise) TypeError: data.map is not a function", which I would like to have display the data retrieved.


Solution

  • Your initial state is,

    yearlyBonds: []
    

    When component first renders it takes initial state. Initially you have empty array. So iteration over empty array giving you the error.

    You can conditionally add your component like,

    { this.state.yearlyBonds.Bonds && <ListTable data={this.state.yearlyBonds.Bonds} />}