Home > Net >  Uncaught (in promise) TypeError: profile.map is not a function in React.js
Uncaught (in promise) TypeError: profile.map is not a function in React.js

Time:10-29

I get the above error every time I try fetching data from a third-party API source(https://randomuser.me/api/?results=50) using Axios. The problem seems to be with the profile.map() function because when I console.log the response received from Axios, it displays all the data. You would find the profile.map() function on the list.jsx element right at the start of return. I have seen the previous solutions and am pretty sure that I have done almost everything that was suggested in those. Here's the code:

screen.jsx displays the list:

import "./screen.css";
import Header from "../header/header";
import List from "../list/list";

const Screen = () => {
    return (
        <div className="mainScreen">
            <Header></Header>
            <List></List>
        </div>
    );
}

export default Screen;

list.jsx

import { useState, useEffect } from "react";
import axios from "axios";
import "./list.css";

const List = () => {
    const [profile, setData] = useState([]);

    useEffect(() => {
        axios.get("https://randomuser.me/api/?results=50").then(
            res => {
                console.log(res.data);
                setData(res.data);
                console.log(profile);
            }
        )
    });

    return (
        <div className="main">
            {/*This is where the error gets thrown*/}
            {profile.map((key, value) => <div className="listCard">
                <div className="userName">
                    <div style={{ margin: "10px 0 10px 20px" }}>Username : {profile[value].login.username}</div>
                </div>
                <div className="details">
                    <div className="topDetails">
                        <div className="nameAndEmail">
                            <div style={{ fontSize: "25px", fontWeight: "bold" }}>Mr Siddhartha Chatterjee</div>
                            <div style={{ fontSize: "20px", color: "rgb(128, 128, 112)", marginTop: "20px" }}>Email: [email protected]</div>
                        </div>
                        <div className="picture">
                            <div className="imageBox"></div>
                        </div>
                    </div>
                    <div className="bottomDetails">
                        <div className="nationality">
                            <div style={{ fontWeight: "bold", fontSize: "22px" }}>User for 6 years</div>
                            <div style={{ fontSize: "20px", marginBottom: "8px" }}>Age: 25</div>
                            <div style={{ fontSize: "20px", marginBottom: "8px" }}>Nationality: Indian</div>
                            <div style={{ fontSize: "18px", marginBottom: "8px" }}>#: 9073030038</div>
                        </div>
                        <div className="address">
                            <div style={{ textAlign: "center", fontSize: "18px", fontWeight: "bold" }}>Address:</div>
                            <div>48, Tarun Sengupta Sarani,</div>
                            <div>Dum Dum, Kolkata, West Bengal, India</div>
                            <div>700079</div>
                        </div>
                    </div>
                </div>
            </div>
            )};
        </div>
    );
}

export default List;

The error :

list.jsx:19 Uncaught (in promise) TypeError: profile.map is not a function
    at List (list.jsx:19)
    at renderWithHooks (react-dom.development.js:14985)
    at updateFunctionComponent (react-dom.development.js:17356)
    at beginWork (react-dom.development.js:19063)
    at HTMLUnknownElement.callCallback (react-dom.development.js:3945)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:3994)
    at invokeGuardedCallback (react-dom.development.js:4056)
    at beginWork$1 (react-dom.development.js:23964)
    at performUnitOfWork (react-dom.development.js:22776)
    at workLoopSync (react-dom.development.js:22707)
    at renderRootSync (react-dom.development.js:22670)
    at performSyncWorkOnRoot (react-dom.development.js:22293)
    at react-dom.development.js:11327
    at unstable_runWithPriority (scheduler.development.js:468)
    at runWithPriority$1 (react-dom.development.js:11276)
    at flushSyncCallbackQueueImpl (react-dom.development.js:11322)
    at flushSyncCallbackQueue (react-dom.development.js:11309)
    at scheduleUpdateOnFiber (react-dom.development.js:21893)
    at dispatchAction (react-dom.development.js:16139)
    at list.jsx:12

CodePudding user response:

Since you are using an async call to load your data, you should check for the profile state to be fetched before displaying the list.
Also, note that I added the [] parameter to the useEffect hook.
This way the get call will be executed only when the component is rendered.

Try to change your code like this:

const List = () => {
  const [profile, setData] = useState([]);

  useEffect(() => {
    loadData();
  }, []);

  const loadData = async () => {
    try {
        const { data } = await axios.get('https://randomuser.me/api/?results=50');
        setData(data);
    } catch (err) {
        console.log(err)
    }
  };

  return (
    <div className='main'>
      {!profile
        ? 'Loading data...'
        : profile.map((key, value) => (
            <div className='listCard'>
              <div className='userName'>
                <div style={{ margin: '10px 0 10px 20px' }}>
                  Username : {profile[value].login.username}
                </div>
              </div>
              <div className='details'>
                <div className='topDetails'>
                  <div className='nameAndEmail'>
                    <div style={{ fontSize: '25px', fontWeight: 'bold' }}>
                      Mr Siddhartha Chatterjee
                    </div>
                    <div
                      style={{
                        fontSize: '20px',
                        color: 'rgb(128, 128, 112)',
                        marginTop: '20px',
                      }}
                    >
                      Email: [email protected]
                    </div>
                  </div>
                  <div className='picture'>
                    <div className='imageBox'></div>
                  </div>
                </div>
                <div className='bottomDetails'>
                  <div className='nationality'>
                    <div style={{ fontWeight: 'bold', fontSize: '22px' }}>
                      User for 6 years
                    </div>
                    <div style={{ fontSize: '20px', marginBottom: '8px' }}>
                      Age: 25
                    </div>
                    <div style={{ fontSize: '20px', marginBottom: '8px' }}>
                      Nationality: Indian
                    </div>
                    <div style={{ fontSize: '18px', marginBottom: '8px' }}>
                      #: 9073030038
                    </div>
                  </div>
                  <div className='address'>
                    <div
                      style={{
                        textAlign: 'center',
                        fontSize: '18px',
                        fontWeight: 'bold',
                      }}
                    >
                      Address:
                    </div>
                    <div>48, Tarun Sengupta Sarani,</div>
                    <div>Dum Dum, Kolkata, West Bengal, India</div>
                    <div>700079</div>
                  </div>
                </div>
              </div>
            </div>
          ))}
      ;
    </div>
  );
};

export default List;

CodePudding user response:

Did you check the results the API returned? It returns something that looks like this

{
    "results": [...],
    "info": {
        "seed": "574cecafce235b8c",
        "results": 50,
        "page": 1,
        "version": "1.3"
    }
}

Since you are doing profile.map, I am assuming that profile should be a list. res.data returned from the API is an object with properties results and info, where results is probably the data you're looking for. To fix your error, you should pass res.data.results into the setData function instead of res.data

useEffect(() => {
    axios.get("https://randomuser.me/api/?results=50").then(
        res => {
            console.log(res.data);
            setData(res.data.results);
            console.log(profile);
        }
    )
});
  • Related