Blog

Front End Development topics with a touch of humor

Order Matters, or WTF, it IS a function!

When did component update, anyway?

September 26, 2020


Anyone who's been coding in JS for a while has known the pain, the frustration, the horror, or:

            MyFunc is not a Function TypeError
        

It's especially annoying, because, well, we wouldn't have called a function if it, you know, wasn't a function. So not only does the program not work, the computer's message is adding insult to injury. It's as if it were being annoying on purpose.

However, being humans, we need to be the bigger person, and acknowledge that the browser is alerting us in the only way it can. It is a very literal kind of creature--that's just how it's made. And we made it that way after all.

To debug, then, we have to think like a computer.

Think like the enemy

When we try to compile our lovely program and get a nasty, weird-font error message, the computer isn't laughing at us, it's just telling us exactly what it sees. The key is, a computer can't see much--at least not at once.

Think of numbers. When you or I look at a number, say 64,000, we take it in at a glance. If we broke it down, probably we see a lump, are cued by the comma which gives it some structure and order, notice the nice clean zeros, and then see the 64 in front. Boom, 64K.

Computers, of course, are not so visually gifted. Besides that they don't have eyes, all they can perceive is a series of little switches--on or off. Due to the human ingenuity of binary, one switch means 0 or 1, two switches add 2, 3, and 4, three switches double that, and so on. But when it comes down to it, the computer only sees what's in front of it--0 or 1, yes or no.

So when the computer throws up a nasty error message, it's simply telling us what it can see, through its tiny, pinprick, 0 or 1 way. To go beyond that would require increases in intelligece that are magnitudes higher.

Sometimes debuggers give us that extra information, and it can be very helpful. Sometimes not. But when it comes down to it, we find the bug, usually, by forcing our wide-ranging, wide-seeing minds into pinprick holes.

About order, then

One of the easiest ways to slip up as a human is to forget about order. In our organic, holistic, free-will -flowing way, we slip up and give the computer an incorrect instruction. Order, you see, is important to competers.

If we see a "4," at a glance we know what it is. But to do the same operation, a computer must first look in the 1s place, then look in the 4s place. 01 means 1; 10 means 3. Order matters.

The same logic holds true in many of our programs. If there is a problem, looking at the order of our code should be one of the first things we think of. Especially when the computer tells us something is not a fuction. Well, we know it's a function--we wrote it, see--look, computer, it's right there:

       function myFunc() {
           console.log(message);
       }
       const message = "hello, friend"
       myFunc();
        

The previous code will throw a nasty message:

           ex.html:37 Uncaught ReferenceError: Cannot access 'message' before initialization
        

Annoying! We have written the function and declared the variable. What else does the stupid computer want from us? Well, this one is easy. Just move the variable declaration above the function.

       const message = "hello, friend"
       function myFunc() {
           console.log(message);
       }
       myFunc();
        

Yay, it works. The only difference is where we declared the variable. Picky, picky, Se単or Computatora...

A slightly more advanced issue will often prove to be the culprit when we get our infamous "is not a function" slap in the face. It is a function, of course, but the function is not accessible at the time the computer needs it. So when you get this nasty message, make sure to look carefully at the order of things--this is one of those times when you're glad you paid attention in stacks and data structure class, right?

I had a particularly annoying case of this in my current React project. React is cool, but it is its own thing.

I had the following situation:

  1. quiz answers in an array in quizData.js
  2. imported into my Quiz component
  3. loaded into state with ComponentDidMount(), a React lifecycle function
  4. brought down from state into JSX and then used with map() method to display onto the screen

But it wouldn't let me map. It said it wasn't a function. I couldn't figure out what was wrong. I knew the quizData stuff was an array, so map should work on it. I knew the quizData stuff had been imported, because I could see it in state. I knew the map function was correctly written, because I was able to do a workaround and use the quizData.js data directly, and it worked.

I was getting the nasty message and I couldn't figure out why. I stared and stared. I tried to make sure I hadn't dropped a semicolon or unintentionally put braces in the wrong place. I looked through the console and examined the state. I closed the program and opened it, hoping magical elves would fix it while I wasn't looking.

Just another day at the office, in other words.

Maybe I would have eventually figured it out, but in this case, I put an alert signal out at FreeCodeCamp and one of the helpful pros there saw what was going on. As the estimable nibble wrote:

       Hi @CactusWren2020. The problem is you are setting state in componentDidMount life cycle method.

       componentDidMount() {
               this.setStateFunction();
           }
           
       React invokes componentDidMount after render has been invoked.  So by the time you set the value of dataQuestion to quizData, the line below which is inside render would have been executed.
        

Forehead slap! Aha! I shoulda seen it, but I hadn't.

So you can see, this is an issue of order. I had everything right except that. My "friend" the computer was getting confused, because at the moment, in its annoying non-human-ness, looked at state, the needed information wasn't there. A millisecond later, it was, of course. Which is why it was so bedeviling.

This is one of those things your React teacher tells you about, but you kind of pass off, thinking, "oh, yeah, that will never happen to me." Really, though, it's hard to absorb a lesson if you don't see the immediate need for it. Now, I see the need: you can bet I'll always give a hard side-eye to ComponentDidMount in the future.

And I'll also remember to pay attention to order.

Image by mohamed Hassan from Pixabay

Icons made by Alfredo Hernandez from www.flaticon.com