Why does without typeof give a warning, but with does not?

Hello! I’m creating a CRUD app to place in a portfolio, and I ran into an interesting warning. I feel it’s difficult to put into words, hence why I’m asking and not researching. This app is coded in React with Redux, and this specific component is class-based.

I’m trying to display $$/hr from a collection of data pieces gathered from a user. These data pieces are in JSON-server, so have to be fetched from an API, and then converted to a number. I have total $$ and total hours. So inside of the render() method, I had:

<div>
{Math.round(this.totalResults() / this.totalHours())}
</div>

That gave me a warning in the console, saying that this specific div (and all of it’s parents) were receiving NaN, even though the number would appear eventually. It also said I had to cast the value to a string. So I tried a ternary.

<div>
{ this.totalHours() && this.totalResults() ? Math.round(this.totalResults() / this.totalHours()) : "Loading..."}
</div>

My thinking is that this should resolve it, because this.totalHours() and this.totalResults() start as null, and only transition to a number when their function is called. But the same error persisted. After this, I changed the ternary to:

<div>
{ typeof this.totalHours() === "number" && typeof this.totalResults() === "number" ? Math.round(this.totalResults() / this.totalHours()) : "Loading..." }
</div>

The warning went away after this. But I have no idea why the first ternary didn’t “work”. Do you have an idea as to why the first ternary consoled an error, but the second did not? The second ternary also seems like a bunch of code for one number, is there any better way to write this code? Consider that I have other places in the component where I need this.totalResults() and this.totalHours() seperately.

Thank you for any help!

If both this.totalResults() & this.totalHours() are functions fetching data from an API, is it possible Math.round() is attempting to assess the expression before both functions have returned their numbers yet?

You could wait for each piece of data to return before doing that by wrapping it in an async function I think.

async function resultsPerHour(resultsCallback, hoursCallback) {
    const results = await resultsCallback();
    const hours = await hoursCallback();
    return Math.round(results / hours)
}

<div>
{resultsPerHour(this.totalResults, this.totalHours)}
</div>