Table content not displaying (foreach tr td)

Hello, the code looks fine to me. Was working just fine before I made some modification elsewhere.
Shoudnā€™t be impacted but here it is: (tbody not displayed)


and I donā€™t get why I try console log hash it displays 4 times when I have only 2 transactions

I donā€™t know if itā€™s related but have some warnings:

Code:

import pageflip from "../data/pageflip.mp3";

import { Typography } from "@material-ui/core";

import { Moralis } from "moralis";

import { useMoralisQuery } from "react-moralis";


function millisecondsToTime (ms) {
    let minutes = Math.floor(ms / (1000 * 60));
    let hours = Math.floor(ms / (1000 * 60 * 60));
    let days = Math.floor(ms / (1000 * 60 * 60 * 24));
    
    if (days < 1) {
        if (hours < 1) {
            if (minutes < 1) {
                return `less than a minute ago`
            } else return `${minutes} minutes(s) ago`
        } else return `${hours} hours(s) ago`
    } else return `${days} days(s) ago`
  }

  const pageflipAudio = new Audio(pageflip);
  const playSound = audioFile => {
    audioFile.play();
}


export default function Transactions ({date}) {

    //playSound(pageflipAudio);

        // set lessThan date
        let nextDate = new Date(date);
        nextDate.setDate(nextDate.getDate()+1);
              
        const { data, error, isLoading } = useMoralisQuery("EthTransactions", query =>
        query
          .greaterThan("block_timestamp", date)
          .lessThan("block_timestamp", nextDate),
          [date],
      );
      
    //console.log("Transactions json: " + JSON.stringify(data, null, 2))
    
    if (!error & data.length > 0) {

    return (
      <table border = "1" bordercolor = "blue">
      <caption>{data.length} transaction(s) {date.toLocaleDateString()}</caption>
      <thead>
      <tr>
      <th scope="col">Transaction</th>
      <th scope="col">Block Number</th>
      <th scope="col">Age</th>
      <th scope="col">Type</th>
      <th scope="col">Fee</th>
      <th scope="col">Value</th>
      <th scope="col">Notes</th>
          </tr>
      </thead>
      <tbody>
      {data.forEach((t) => {
          console.log("hash" + t.attributes.hash)
          return(
    <tr>
        <td><a href='https://etherscan.io/tx/${t.attributes.hash}' target="_blank" rel="noopener noreferrer">${t.attributes.hash}</a></td>
        <td><a href='https://etherscan.io/block/${t.attributes.block_number}' target="_blank" rel="noopener noreferrer">${t.attributes.block_number}</a></td>
        <td>${millisecondsToTime(Date.parse(new Date()) - Date.parse(t.attributes.block_timestamp))}</td>
        <td>${t.attributes.from_address == Moralis.User.current().get('ethAddress') ? 'Outgoing' : 'Incoming'}</td>
        <td>${((t.attributes.gas * t.attributes.gas_price) / 1e18).toFixed(5)} ETH</td>
        <td>${(t.attributes.value / 1e18).toFixed(5)} ETH</td>
        <td><input type="text" id="name" name="name"></input><button>Save</button></td>
    </tr>
      ); })}
      </tbody>
      </table>
    );

}
else {
    return (<Typography>No transactions</Typography>);
}
}

@nadtn

use data.map instead of data.forEach

1 Like

Regarding duplicated messages in the console.log - your components got rerendered a lot of times because of the bad optimization.

I suggest you to take learn more about useEffect hook

Thanks Yomoo! It fixed the issue, the tbody is indeed there now. Iā€™ll have to dig into it to see the difference betwwen bothā€¦

So your code should b like this. Use useState and useEffect:

export default function Transactions({ date }) {
  let nextDate = new Date(date);
  nextDate.setDate(nextDate.getDate() + 1);
  const { data, error, isLoading } = useMoralisQuery(
    "EthTransactions",
    (query) =>
      query
        .greaterThan("block_timestamp", date)
        .lessThan("block_timestamp", nextDate),
    [date]
  );

  const [hashes, setHashes] = useState([]);

  useEffect(() => {
    if (data) {
      setHashes(data);
    }
  }, [data]);

  if (!error & (hashes.length > 0)) {
    return (
      <table>
           <tbody>
          {hashes.map((t) => {
            console.log("hash" + t.attributes.hash);
            return (
              <tr key={t}>{t}</tr>
           }
        </tbody>
    </table>
 )}
});

Iā€™m not sure if this example code will really work. But you should to understand the way you need to use the React after my example

The thing is Iā€™m using it for the dateā€¦

 const [date, setDate] = useState(new Date());


      useEffect(() => {
        if(isAuthenticated){
            onChangeDate(date); 
            //console.log("date in useEffect: " + date)
    }
  }, [isAuthenticated]); 

    async function onChangeDate(nextValue) {
      setDate(nextValue);
      //console.log("nextValue: " + nextValue)
      //console.log("date: " + date)
      getFile();
    }

And
<Transactions date={date}/>
Is it the way to use it? Because after selecting the 2nd date there is gap between:
nexValue in onChangeDate and date of useSrate.

Should I use the useEffect for date in Assets.jsx or add it in Transations.jsx?

Hey @nadtn

Iā€™m really happy to help you, but are you sure that you are ready to create an app on React? I canā€™t really write a whole app for you :sweat_smile:

1 Like

I said Iā€™ll take the time to learn it after the ETHOnline, bear with me until October 10thā€¦ :sweat_smile:
But I already learned a lot thanks to you sorry for the bother though.
Want to show the cool things you can do with Moralis (and learn in the process)ā€¦

2 Likes

Nicee. I wish you success :raised_hands:

1 Like