Making a Simple D3 Visualization &The Stupid JS Mistakes I Made
[1, 2, 3, 4, 5, 10, 11, 12].sort() is [1, 10, 11, 12, 2, 3, 4, 5]
ints: You will be sorting those members by their Unicode equivalent. MDN Sort Docs told me this, simply and clearly. I needed the min and max of an array and (ok, yes, this is bad) just sorted the thing and took the first and last element. Yes, I get it, this is bad, but it was really weird that I got a different value from
var m = d3.min(arrayThing) than from
x.sort(); var m = x, which led me to learn about this.
Side Note: Sorting an array to get the min and max is bad because you reassign so many variables on a journey to simply assign the two items you really want: the min and the max.
One of my functions took a big array from another function, then chopped it up and sometimes overwrote the occasional entry in this array. Imagine my dismay when I realized if I called this function a second time or used the array again after this function had mangled it, the data had changed!
I checked this StackOverflow answer first. Primitives by copy, objects by “copy of reference”. My takeaway from this is — hopefully not bad — that you need to clone the object if you want to mutate it in your function.
There is certainly more to discuss here: scope, passing arguments, etc. If you have comments, I am all ears. Hit me up on Twitter or here on Medium.
Copying Objects by Serializing & Deserializing in JSON is a Bad Idea™
After I discovered that passing by reference would have an impact on my code, I settled on cloning the object. This didn’t feel great, but I saw this StackOverflow answer on Efficiently Cloning JS Objects, should have realized “Efficiency” wasn’t the main target I was shooting for. One important thing I overlooked until a second reading was that the author of that comment mentions
Date conversions would not work in this case.
In general, I disliked this practice because even if you don’t use
Date objects, which I did, it limits you to not using
Date objects in the future and additionally I feel like (but do not have conclusive evidence to support) that this may not be kind in other edge cases. Here is one, you decide if you would ever do this:
undefined is not your friend
At some point, my code contained something like this:
undefined and goes on about it’s business.
This is something I need to watch out for more, I’ve included linting in my workflow now, but read on to find the real solution…
Most of these problems could have been solved by Unit Tests
Sometimes when we start a project, we think it’ll be so quick and easy to finish it that we can just write a few functions, strap them together and see our results. Nothing could have been farther from the truth in this instance.
Maybe because I did this outside work I was more rushed and felt like I couldn’t dedicate the time to testing, but I was wrong.
- Had I written a unit test to cover the calculation of the domain of my graph, I would have caught that nasty min/max bug earlier.
- Had I written a unit test to cover the splitting of segments, I would have discovered that I flipped the ratio numerator and denominator very quickly.
- Indeed, I would have discovered that the output from a number of functions was off or incorrect in a number of situations and for this reason, I regret not writing unit tests for the code.
In the next week or so, look for more unit tests in my project, most likely with MochaJS.
And for reading so far, here is a graph of my 50 mile run, with average speed bucketed into smaller time segments so it’s easier to see general trends across the graph.
Here’s a link to the repo — you are welcome to contribute PRs for anything you desire (even formatting!) and if anything doesn’t make sense, please do reach out to me.