0

i am building a report component that fetches data from the API and spits it out to the dom.

My issue is the following:

enter image description here

I get all the data by using UseEffect and then i loop over the array of objects to get the exact data that i need to insert into the table cells, like this9 one example):

 <tr className="max-w-lg">
    <td className="px-6 py-4 text-sm text-gray-500">
        Annual Income
    </td>
  {report.map((value, i) =>
  <td className="px-6 py-4 text-sm text-gray-500">
   ${value.income}
  </td>)}                                  
 </tr>

that's how it looks on the screen. enter image description here

The issue starts with the address and purchase data - since i do not need it for each year ( address/name is fixed and the down payment is also fixed) i do not want or need to loop over the array to extract it, But the problem is that if i use the following code:

<div
   className="grid justify-items-center border-4 text-lg"
>
   {report && 
      <div>
        <h2>Report Name: {report[0]["address"]}</h2>
        <h3>Out Of Pocket: {Math.round((report[0]["price"]) * (report[0] 
           ["down_payment"]))}
        </h3>
     </div>                   
   }
 </div>

it throws an error because the component is rendered before the data is fetched, and although i declared a condition that only if report is true then render the data, it still throws an error, can anyone advise how to solve it ?

this is the full code of the component,

import React, { useEffect, useState } from 'react'
import { useParams } from 'react-router-dom';

function Reports() {
    const [report, setReport] = useState([]);
    const [address, setAdress] = useState('');
    const {id} = useParams();

    console.log(id)

    // let id = parseInt(idObjStr["id"].slice(1));

    // console.log(id)

    const getReport = () => {
        let url = `http://localhost:3000/reports/${id}`
        
        fetch(url)
        .then(res => res.json())
        .then(data => setReport(data))

    }

  
    console.log(report)
    
    // console.log(report.map(x) => x.)
    useEffect(() => {
        getReport();
    }, []);

    return (
    
                <div className="border-b border-gray-200 shadow">
                    <div
                        className="grid justify-items-center border-4 text-lg"
                    >
                        {report && 
                        <div>
                        <h2>Report Name: {report[0]["address"]}</h2>
                        <h3>Out Of Pocket: {Math.round((report[0]["price"]) * (report[0]["down_payment"]))}</h3>
                        </div>
                      
                        }
                    </div>
                    <table className="divide-y divide-gray-900 table-fixed mt-3">
                        <thead className="bg-gray-50 flex-wrap">
                            <tr>
                                <th className="px-6 py-2 text-xs text-gray-500">
                                    ID
                                </th>
                                    {report.map((value, i) =>
                                        <th className=" flex-autopx-6 py-4 text-sm text-gray-500">Year-{value.year}
                                        </th>)}
                            </tr>
                        </thead>
                        <tbody className="bg-white divide-y divide-gray-300">
                            <tr className="max-w-lg">
                                <td className="px-6 py-4 text-sm text-gray-500">
                                    Annual Income
                                </td>
                                    {report.map((value, i) =>
                                        <td className="px-6 py-4 text-sm text-gray-500">${value.income}
                                        </td>)}                                  
                            </tr>

                            <tr className="max-w-lg">
                                <td className="px-6 py-4 text-sm text-gray-500">
                                  Expenses
                                </td>
                                    {report.map((value, i) =>
                                        <td className="px-6 py-4 text-sm text-gray-500">(${value.expenses.property_taxes + 
                                        value.expenses.property_vacancy_rate + value.expenses.annual_property_repairs})
                                        </td>)}                                  
                            </tr>

                            <tr className="max-w-lg">
                                <td className="px-6 py-4 text-sm text-gray-500">
                                  Financial Expenses
                                </td>
                                    {report.map((value, i) =>
                                        <td className="px-6 py-4 text-sm text-gray-500">(${
                                        value.loan.principal + value.loan.interest})
                                        </td>)}                                  
                            </tr>

                            <tr className="max-w-lg bg-black white">
                                <td className="px-6 py-4 text-sm text-white font-bold">
                                  NOI
                                </td>

                                    {report.map((value, i) =>
                                        <td className="px-6 py-4 text-sm text-white font-bold">
                                            ${value.income - 
                                            (value.expenses.property_taxes + value.expenses.property_vacancy_rate + value.expenses.annual_property_repairs) -
                                            (value.loan.principal + value.loan.interest)
                                            }
                                       
                                        </td>)}                                  
                            </tr>
                            
                         
                            <tr className="max-w-lg bg-black white pt-96">
                                    <td className="px-6 py-4 text-sm text-white font-bold">
                                        COC
                                    </td>

                                    {report.map((value, i) =>
                                        <td className="px-6 py-4 text-sm text-white font-bold">
                                            %{parseFloat((value.income -
                                                (value.expenses.property_taxes + value.expenses.property_vacancy_rate + value.expenses.annual_property_repairs) -
                                                (value.loan.principal + value.loan.interest)) / (value.down_payment * value.price / 100)).toFixed(2)
                                                // /(report.down_pmt)
                                            }

                                        </td>)}
                            </tr>
                            <br></br>
                            <tr className="max-w-lg bg-black white pt-96">
                                    <td className="px-6 py-4 text-sm text-white font-bold">
                                        Equity
                                    </td>

                                    {report.map((value, i) =>
                                        <td className="px-6 py-4 text-sm text-white font-bold">
                                            ${Math.round(value.equity) 
                                                
                                                // /(report.down_pmt)
                                            }

                                        </td>)}
                            </tr>
                            
                            
                     
                        </tbody>
                    </table>
                </div>
      
    )
}

export default Reports
  • 2
    Try `{report.length && ...`. Arrays are implicitly _truthy_, even when empty – Phil Mar 21 '22 at 23:47
  • Does this answer your question? [Check if an array is empty or exists](https://stackoverflow.com/questions/11743392/check-if-an-array-is-empty-or-exists) – Phil Mar 21 '22 at 23:48
  • +1 to what Phil says. You could also set another state to use as a notification. Set the state to loading right before you make a request, and then success or failure after the request completes. This allows you to add good messaging instead of just popping the data into the component. – Alex Mar 22 '22 at 00:26

0 Answers0