0

I am new to react, i am trying to use async function but i have facing the following error "Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead."

import {
  Badge,
  Card,
  CardHeader,
  CardFooter,
  DropdownMenu,
  DropdownItem,
  UncontrolledDropdown,
  DropdownToggle,
  Media,
  Pagination,
  PaginationItem,
  PaginationLink,
  Table,
  Container,
  Row,
  UncontrolledTooltip,
} from "reactstrap";
// core components

import Header from "components/Headers/Header.js";
  import 'react-toastify/dist/ReactToastify.css';
import { Link } from "react-router-dom";

import axios from "axios";
import data from "./data";
var apitoken= localStorage.getItem('apitoken');

const api=axios.create({baseURL:"https://IP/DeAPI/api/v1/account"})
const options = {
  headers: {'Authorization': apitoken}
}

const asynchronousFunction = async () => {
  const response = await api.get("/",options)
 
  window.input=response.data.response


}

const mainFunction = async () => {
  const result = await asynchronousFunction()
  return result
}
const state = { students:window.input}
//console.log(window.input);
  const renderTableData=async ()=> {
    console.log("test"+await mainFunction())
    if(state.students) {
    
    
      return state.students.map((student, index) => {
         const { id, name, age, email } = student //destructuring
         return (
            <tr key={id}>
               <th scope="row">
                      <Media className="align-items-center">
                        <a
                          className="avatar rounded-circle mr-3"
                          href="#pablo"
                          onClick={(e) => e.preventDefault()}
                        >
                          <img
                            alt="..."
                            src={
                              require("../../assets/img/theme/bootstrap.jpg")
                                .default
                            }
                          />
                        </a>
                        <Media>
                          <span className="mb-0 text-sm">{id}   </span>
                        </Media>
                      </Media>
                    </th>
                    <td>
                      <Badge color="" className="badge-dot mr-4">{name}</Badge>
                    </td>
               <td>
                      <Badge color="" className="badge-dot mr-4">{age}</Badge>
                    </td>
                    <td>
                      <Badge color="" className="badge-dot mr-4">{email}</Badge>
                    </td>
                    
            </tr>
         )
      })
    }
    else
    {
      console.log("Something went wrong")
    }
   }
  
const Accounts = () => {

 
  return (
    <>

      <Header />
      {/* Page content */}
      <Container className="mt--7" fluid>
        {/* Table */}
        <Row>
          <div className="col">
            <Card className="shadow">
              <CardHeader className="border-0">
                <h3 className="mb-0">All Account</h3>
              </CardHeader>
              <div>
          
          
         </div>
              <Table className="align-items-center table-flush" responsive>
                <thead className="thead-light">
                  <tr>
                    <th scope="col">Account Name</th>
                    <th scope="col">Phone</th>
                    <th scope="col">Email</th>
                    <th scope="col">Account Owner</th>
                    {/* <th scope="col">Pincode</th> */}
                    <th scope="col" />
                  </tr>
                </thead>
                <tbody>
                {renderTableData()}
                 
                </tbody>
              </Table>
             
          
            </Card>
          </div>
        </Row>
       
      </Container>
    </>
  );
};

export default Accounts;

What have i done wrong here;

I am trying to get the student data from api and render it in the component dynamically.

The issue is with

<tbody>
                {renderTableData()}
                 
                </tbody>

If i removed it its working,

Thanks in advance

3 Answers3

0

You should use the lifecycle hook useEffect to fetch async data (when working with functional components).

you also want to save your data in state. This is the default way to work with apis in react. Simply storing it in a variable will not work due to React's async behaviour.

Your error here is that you are trying to render a promise, which is not valid JSX

you can use the hook like this

const [state, setState] = useState({})
...
useEffect(() =>{
async(() =>{
   const data = await mainFunction()
   setState(data)
})()
}, []) //empty array means to only run once
Kristoffer Tølbøll
  • 3,157
  • 5
  • 34
  • 69
0

You should not put anything except JSX into JSX. The problem is that async function returns Promise instead of JSX. You should rather use React.useEffect and React.useState to solve the loading problem. Let me show you.

Acutally another problem might be returning an array. Try wrapping it into <>...</> as I did.

import * as React from "react";
import {
  Badge,
  Card,
  CardHeader,
  CardFooter,
  DropdownMenu,
  DropdownItem,
  UncontrolledDropdown,
  DropdownToggle,
  Media,
  Pagination,
  PaginationItem,
  PaginationLink,
  Table,
  Container,
  Row,
  UncontrolledTooltip,
} from "reactstrap";
// core components

import Header from "components/Headers/Header.js";
import 'react-toastify/dist/ReactToastify.css';
import { Link } from "react-router-dom";

import axios from "axios";
import data from "./data";
var apitoken= localStorage.getItem('apitoken');

const api=axios.create({baseURL:"https://IP/DeAPI/api/v1/account"})
const options = {
  headers: {'Authorization': apitoken}
}

const TableData = () => {
  const [students, setStudents] = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  React.useEffect(async () => {
    const response = await api.get("/",options);
    setStudents(response.data.response);
    setLoading(false);
  }, []); 
  if (loading) {
    return <>Loading...</>;
  }
    
  return (
    <>
      {students.map((student, index) => {
        const { id, name, age, email } = student //destructuring
        return (
          <tr key={id}>
            <th scope="row">
              <Media className="align-items-center">
                <a
                  className="avatar rounded-circle mr-3"
                  href="#pablo"
                  onClick={(e) => e.preventDefault()}
                >
                  <img
                    alt="..."
                    src={
                      require("../../assets/img/theme/bootstrap.jpg")
                        .default
                    }
                  />
                </a>
                <Media>
                  <span className="mb-0 text-sm">{id}   </span>
                </Media>
              </Media>
            </th>
            <td>
              <Badge color="" className="badge-dot mr-4">{name}</Badge>
            </td>
            <td>
              <Badge color="" className="badge-dot mr-4">{age}</Badge>
            </td>
            <td>
              <Badge color="" className="badge-dot mr-4">{email}</Badge>
            </td>
          </tr>
        )
      })}
    </>
  )
}
  
const Accounts = () => {
 return (
    <>

      <Header />
      {/* Page content */}
      <Container className="mt--7" fluid>
        {/* Table */}
        <Row>
          <div className="col">
            <Card className="shadow">
              <CardHeader className="border-0">
                <h3 className="mb-0">All Account</h3>
              </CardHeader>
              <div>
          
          
         </div>
              <Table className="align-items-center table-flush" responsive>
                <thead className="thead-light">
                  <tr>
                    <th scope="col">Account Name</th>
                    <th scope="col">Phone</th>
                    <th scope="col">Email</th>
                    <th scope="col">Account Owner</th>
                    {/* <th scope="col">Pincode</th> */}
                    <th scope="col" />
                  </tr>
                </thead>
                <tbody>

                <TableData />
                 
                </tbody>
              </Table>
             
          
            </Card>
          </div>
        </Row>
       
      </Container>
    </>
  );
};

export default Accounts;
Dominik Dosoudil
  • 899
  • 8
  • 15
0
<tbody>
{state.students?.map((student, index) => {
         const { id, name, age, email } = student //destructuring
         return (
            <tr key={id}>
               <th scope="row">
                      <Media className="align-items-center">
                        <a
                          className="avatar rounded-circle mr-3"
                          href="#pablo"
                          onClick={(e) => e.preventDefault()}
                        >
                          <img
                            alt="..."
                            src={
                              require("../../assets/img/theme/bootstrap.jpg")
                                .default
                            }
                          />
                        </a>
                        <Media>
                          <span className="mb-0 text-sm">{id}   </span>
                        </Media>
                      </Media>
                    </th>
                    <td>
                      <Badge color="" className="badge-dot mr-4">{name}</Badge>
                    </td>
               <td>
                      <Badge color="" className="badge-dot mr-4">{age}</Badge>
                    </td>
                    <td>
                      <Badge color="" className="badge-dot mr-4">{email}</Badge>
                    </td>
                    
            </tr>
         )
      }) 
} 
</tbody>

Try this one instead

crispengari
  • 7,901
  • 7
  • 45
  • 53