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