I just spent an hour searching for how I could have gotten an

Uncaught TypeError: Cannot set properties of null

javascript. I checked the spelling of the element whose property I was trying to set and knew that element wasn’t null because the spelling was the same in the code as in the HTML. I also knew my element was loading, so it wasn’t that either.

Turns out no, the element was null. I was trying to set " NameHere" when the element’s actual name was “NameHere”.

Off by a single space. No wonder I thought the spelling was the same—because all the non-whitespace was identical. (No, the quotation marks slanting in the second NameHere and being totally vertical in the first NameHere wasn’t a part of the error, I am typing them all vertical and either Lemmy or my instance is “correcting” them to slanted for the second NameHere. But that is also another tricky-to-spot text difference to watch out for!)

And what did not help is that everywhere I specifically typed things out, I had it correct with no extra spaces. Trying to set " NameHere" was the result of modifying a bunch of correct strings, remembering to account for a comma I put between them, but not remembering to account for the space I added after the comma. In short, I only ever got to see " NameHere" written out in the debugger (which is how I caught it after like 30 repeats of running with the debugger), because everywhere I had any strings written out in the code or the HTML it was always written “NameHere”.

I figured I’d post about it here in case I can help anyone else going crazy over an error they did not expect and cannot figure out. Next time I get a similar error I will not just check spelling, I’ll check everything in the name carefully, especially whitespace at the beginning and end, or things one space apart being written with two spaces instead. Anyone else have a similar story to save the rest of us some time?

  • Ephera
    link
    fedilink
    English
    24 months ago

    I am curious if it is viable to do it just pure JS or if I really need to learn some popular frameworks/libraries. I have no idea where this resistance comes from, guessing it’s perhaps because “oh wow a whole framework” seems more intimidating than “learn to fix your code in a language you already know a little bit”, as someone unfamiliar with frameworks. I should probably learn them anyways.

    I mean, I am primarily a backend guy. You should probably ask some frontend person. In my experience, if you get a job in a company, you’re pretty much always going to be using one of these frameworks. From my little experience with Angular and React, it felt like you could learn them quite late and your JS knowledge would still apply. But these frameworks do have big ecosystems, with many supporting libraries, and the more projects you do with them, the more of these libraries you’re gonna know, which can be invaluable experience.

    I do have some of the code commented but I also recently found according to https://refactoring.guru that this is bad?

    There is a bit of a culture war going on at the moment.
    What everyone agrees on is that commenting why you implemented something a certain way (when it’s not obvious) is always a good idea.
    But describing what you did is ideally superfluous, because your code is readable enough to tell the same.
    If it’s not, then you should work on code readability instead, or try to reduce code complexity. In particular, in my experience most of the time, what people want to describe in a comment, should be a function name (by pulling the code out into a function) or a variable name or even a log statement. Because if it’s not obvious where you’re declaring that code, it’s not going to be obvious where you’re using that function/variable (or in the console output) either.

    Comments also particularly have these problems:

    • Comments can get outdated. You might explain in a comment a certain behavior, then someone changes that behavior and doesn’t update the comment. Then the comment is actively misleading.
    • Comments explain complexity rather than eliminate it. If you feel the need to explain what the hell a piece of code does, you’re admitting that it’s too complex. Sometimes, this just cannot be fixed. But many times, a refactoring is more useful, because others reading your code don’t anymore have to understand the complexity, if it’s gone.
    • Comments stop being read when there’s too many. Devs will gladly not read comments, when they all just say useless stuff like //add user to list. If you leave out those comments, and instead only use them where you really need to point something important out, devs will be much more likely to read that.

    But yeah, I am more on the side of disliking comments. Others might potentially say that my code is difficult to read, because they’re used to a clear-text explanation, although I don’t know, I haven’t yet actually gotten that feedback. I do invest a lot of time on code readability, because in my experience it pays off.

    Final thing: most resources I am aware of are for cleaning up object-oriented stuff. Wondering about resources for cleaning up non-object-oriented stuff and when I should and should not be doing object-oriented stuff, seeing as I did not write this raw JS object-oriented. (Yes, I know you can still kind of imitate some of the design patterns anyways, just curious.)

    Right, next culture war. I wouldn’t say I’m anti-object-orientation, but people definitely like to overdo it. And when I say people, I do also mean myself, when I came from a JVM language to TypeScript a few years ago.
    And just to clarify, I distinguish between merely using objects (i.e. logic associated with data types) and object-orientation, which has the whole range of inheritance, encapsulation and whatnot.
    Using objects is undoubtedly really useful (even if in an untyped language like JS, it might be less so).

    But the full-blown object-orientation principles are in my experience, and I believe in the experience of many, primarily useful for writing big monolithic applications like one did in the 90s and 2000s. Since then, there has been a general learning and technological advances (better build tools, containerization, IDEs etc.), which means people tend to go for smaller or more modular codebases, which make the object-orientation principles far less useful. And since these principles do add complexity, they’re being seen much less favorably.

    Which is a long-winded way to say, I do understand why you’re finding more resources for dealing with object-orientation, because there’s more of a need for it.
    Non-object-oriented code often goes for relatively simple structures, which just don’t need as much refactoring. You might move a function or a data type into a different file, but that’s mostly it.

    As for advice on that:

    • Move your code around, so it’s grouped semantically in a way that a human might expect.
    • Try to keep your control flow and data type references tree-shaped when possible. Unless you need it, you want to avoid circular references.
    • In particular, you might also want to keep your code kind of in ‘layers’ of abstraction. At the top, you’ve got high-level logic, which mostly just lists individual function calls. And then those functions do the actual work and might live in a separate file, in e.g. a sub-folder in the file structure.
    • Generally, it’s a good idea to try to extract input/output code from your core logic. So, if you’ve got a backend where you need to send requests to, then you probably want a separate file/folder with just code that does the detail work for calling the backend. Things like converting data types into the right format, error handling and such, you don’t want that cluttering up your core logic.
      Similarily, code for displaying to the user often concerns itself with details, like how to format a string, which you want to isolate from your core logic ideally, too.
      In my experience, JS or UI code in general is tricky for less seasoned devs in that regard, because it’s often so easy to just quickly send something to the backend or UI in your core logic. And in particular, you may also hardly have any core logic to begin with. But yeah, in the long run, it’s still good to do, because it reduces the code complexity.
      And frankly, even just having a file where all the backend calls are collected, has proven useful many times, because you can easily make adjustments when the backend API changes or you want to introduce authentication or things like that.

    Also need to find out if if’s okay to have the same thing appear twice in the HTML and how to put that in a constant if not, or if it would be better to programmatically generate it because a lot of it is pretty repetitive and the same string everywhere (except for the name attribute sometimes).

    Yeah, I tried to sneak that in via edit into my previous comment, but I think, you already responded before I did. So yeah, check up there.