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?
When cd drives first came out I got one and then wrote my own program in assembly to display all the information about the drive and disc that you normally can’t see (because it was just drive E: or whatever to DOS/Windows).
I named the program cd. It took me way too long to figure out my mistake.
I had an issue with a balanced binary tree. At some point, it would bomb out when adding another node.
It took me ages to recognize that at one point of the balancing algorithm, instead of
if (something) {
[...]
} else {
[...]
}
I had written
if (something) {
[...]
} {
[...]
}
I once spent three days , 30 hours, because I was writing text with new lines as a binary stream.
4 keystrokes to fix
Not sure if this question is too noobish for !programming@programming.dev so I posted it here just in case.
I mean, that’s kind of the first big lesson you learn from experience, to put as little trust in humans as possible. My immediate thought was whether one could’ve put that name into a constant somewhere, so you only had to spell it correctly once or twice.
Frankly, that also kind of makes it difficult for me to answer your question, because when I fuck up like that, I don’t remember it as a dumb mistake that I shouldn’t do next time, but rather I see it as an indicator that my precautions against human errors aren’t good enough. They shouldn’t be easy-to-solve, they should be medium-difficult-to-never-see-them-again.
I actually wrote it just once. It acquired the space like this:
I concatenate a bunch of strings together, and add a comma and space between them so I could get stringOne, stringTwo, stringThree
etc. I later need to decompose that. I remembered I separated stuff with a comma, but forgot about the space following the comma and that is how I ended up having to deal with " NameHere" vs “NameHere” without having actually written NameHere several times in my code. Is there a better way to go about this?
I have also just read my post again and it explicitly contradicts “I actually wrote it just once”. Not sure if I did write it multiple times and merely forgot as I typed this comment and claimed to write it just once, or if I just pretended I wrote it multiple times when it was only once so I could simplify explaining my problem. For the purpose of my question though, let us pretend I did write it once. I promise I am aware that strings that are frequently used should be made constant, although I could use more specifics on what “frequently used” is (more than once?) and I’m wondering if you actually should not really use strings at all and always go for constants.
I mean, it’s hard to tell why you’re doing what you’re doing there. Sometimes with JavaScript and frontend code, certain crimes are just a necessary evil.
But yes, I am calling it a crime to concatenate strings and decompose them afterwards.
For one, human errors like what you did are possible.
You could mildly improve on that by pulling out two functions:
encode_blah_list_to_string()
decode_blah_list_from_string()
You could then at least define those directly below each other in the code, making it easy to define them, so they work together.
If you’ve already looked into unit tests, this would also be an incredibly easy and useful unit test to write. In your test code, you would define a list, then call the encode-function, take the result of that and call the decode-function, and then the result of that should be identical to the original list.
Having said that, encoding things as a string with custom logic like that, has another big problem:
It could happen that e.g. stringTwo
contains “Hello, World”. Suddenly, you’d be splitting in the middle of stringTwo
, when you’re decoding.
So, ideally you can avoid it completely and pass around the array directly.
If you can’t, the next best thing would be to encode it in JSON. It will handle all these edge cases, and it’s a clearly defined way of encoding and decoding, so you wouldn’t even need to pull it out into functions.
If it’s some custom format that you display to the user (and ideally the user is aware that commas are bad), then yeah, you would have to do the custom encoding and decoding implementation, like described above.
I am aware that strings that are frequently used should be made constant, although I could use more specifics on what “frequently used” is (more than once?) and I’m wondering if you actually should not really use strings at all and always go for constants.
Alright, so if it’s a string where it matters that it’s spelled exactly correctly and it will be used in more than one place in your codebase, then I would always pull it out into a constant.
If it’s an unchanging value that you just pass to a library in one place in your code, like a timezone name, then I wouldn’t usually pull it out into a constant, unless I feel like it helps to make this constant clearly visible at the top of the file.
For example, it rarely happens that a constant is unquestionably correct and unchanging, so making your choice prominently visible can be useful. Of course, if you’re not running in a browser, then these kind of arbitrarily chosen ‘constants’ should probably be configurable in a configuration file.
If it’s a UI description text, then it might make sense to pull it out into a constant, just to unclutter your code.
Or if you’re working with a localization framework, then you’d have pseudo-constants for that anyways, which would get replaced with the respective language text at runtime.
But yeah, I definitely wouldn’t say you should always go for constants. They add a layer of indirection, meaning someone reading your code won’t know what the actual string is without checking the constant.
But if it needs to be the same value in two places, then this layer of indirection is definitely worth it and makes it easier to reason about your code.
I will also say that if we weren’t talking about JavaScript, I would be much more contrarian to strings. Partially because JS is used in frontend a lot, where you do need to deal with strings anyways. And partially, because JavaScript is dynamically typed, so it just doesn’t have as many tools to deal with strings otherwise.
In our backend Rust codebase at work, I do tell our juniors, if you’re typing a quotation mark and you’re not doing it for logging or error messages, then do consider, if that’s really what you want. Usually, they want an enum instead, or if they really do need to pass around a string, then they should use a newtype, which is basically a typed wrapper, so you can’t accidentally pass the wrong kind of string into a function.
I spent three days trying to get a RaycastCommand (Unity’s jobified raycasts) working to get multiple hits per raycast. Should have been easy, according to the docs:
The result for a command at index N in the command buffer will be stored at index N * maxHits in the results buffer.
If maxHits is larger than the actual number of results for the command the result buffer will contain some invalid results which did not hit anything. The first invalid result is identified by the collider being null
maxHits The maximum number of Colliders the ray can hit
Well, no. I was getting super weird results and couldn’t get it to work properly. First thing I checked was if I’m getting two+ hits for any of the raycasts, because you simply can’t trust Unity. And I was getting multi hits, but seemingly at random.
The error? I was sorting the hits by distance using bubblesort, and made a simple error with index in it. Which resulted in me seemingly getting two hits per ray sometimes, but it was just a result for another ray moved there by faulty bubblesort. Because unity actually doesn’t support multiple hits per ray.
I couldn’t find the original thread about the issue (which was two years old by the time I was dealing with it), which had an amazing reply from Unity:
I have discussed it with an engineering team, and RaycastCommands don’t support multiple hits because it was difficult to implement. The documentation just doesn’t explains it really well
The fuck doesn’t explain it very well??? It literally describes a parameter that sets max hits per ray and tells you how to get the multi hits from results…
Fuck unity :D