Recent Blog Posts by Ben Nadel
Working Code Podcast - Episode 197: Potluck
On this week's show, we talk about a variety of topics. Adam examines the notion that you get promoted into the job that you're already doing. Carol discusses the AI training course that she just took in order to start using chat-bots in government work. Tim talks about leading your team through hard times; and how to focus on the one most important goal. And I lament the idea that I don't spend enough time sitting alone with my thoughts and connecting with the world at large... read more →
Using Canonicalize() To Embed Emoji In Email Subject Lines In ColdFusion
In my previous post on using canonicalize() to render emoji characters in ColdFusion, I mentioned that this technique can be helpful in contexts where HTML entities aren't well supported. Email subject lines appear to be one such context; as I discovered yesterday when trying to add a police siren emoji to an email subject line for a time-sensitive (expiring) link. To get around this, we can use the canonicalize() function to embed emoji safely within email subject lines in our CFML... read more →
Using Canonicalize() To Render Emoji In ColdFusion
In ColdFusion, the canonicalize() function is used to reduce a given string down to its simplest form. This is typically used during user input sanitization and validation; but, this normalization process can also be used to convert HTML entities into their associated characters. In other words, we can use the canonicalize() function to convert encoded emoji characters into native emoji glyphs... read more →
Working Code Podcast - Episode 195: Isn't Worth The Squeeze
On a recent episode of the Economics of Everyday Things, Zachary Crockett explains that the perfect amount of money laundering is not zero. Attempting to eliminate all money laundering would be so disruptive to commerce that the net-loss of such an extreme position would far outweigh the potential benefits. Over here on our podcast, that got us thinking about areas within our work in which lofty goals aren't worthwhile. Topics include error logs, code coverage, feature completeness, consistency, time tracking, elegance, and requirements gathering... read more →
Dynamically Define For-Loop Increment In ColdFusion
In my Lopem Ipsum generator, I take a collection of paragraphs and I split them up into sections of random lengths. To do this, I iterate over the collection using a dynamically defined increment. In other words, the "step" value is randomly assigned on every for-loop iteration. I don't think I've ever done this before; and it worked like a charm. So, I thought it was a mechanic worth sharing in ColdFusion... read more →
Generating Lorem Ipsum Text In ColdFusion
As a fun code kata for my /utils section, I wanted to create a Lorem Ipsum text generator. Lorem Ipsum is a common way to create placeholder text during the design phase of the prototyping process. Lorem Ipsum text uses Latin words to embody English-looking text distributions without the distraction of being readable (except by those 4 people who took Latin classes in high school). What follows is my attempt to generate this placeholder text in ColdFusion... read more →
ColdFusion: Comparison Method Violates Its General Contract
This week, a single instance of an error showed up in my ColdFusion logging: "Comparison method violates its general contract!". The stacktrace pointed to something in the Java layer called TimSort; which is what ColdFusion's Array.sort() method is using under the hood. This error may be thrown if the .sort() callback / operator doesn't adhere to the set of requirements defined by the Comparable interface... read more →
Working Code Podcast - Episode 193: Bonding In The Foxhole
Without a doubt, there is a special bond formed between people who've shared an intense experience. At work, we see this all the time during incident triage and remediation—there is something truly special about those Zoom calls in which everyone on the team is suddenly on the same page and is working with a singular purpose. But, do we end up glorifying these metaphorical foxholes? Can we build those lasting bonds during the good times? Or, is there something unique about a company that has gone through trial-by-fire?.. read more →
TODO: Granting Yourself Permission To Move Forward
I just read Chris Ferdinandi's latest newsletter, Gardening and code, about the importance of solving the problems in front of you. In it, Chris touches upon an issue that we all struggle with at some point: feeling like our first solution has to be the perfect solution. It reminded me of a powerful cognitive tool that I use in my own programming: the TODO: comment... read more →
Signals And Array Mutability In Angular 18
Like many change detection mechanisms, Signals in Angular 18 rely on reference changes in order to trigger change detection. When consuming simple values, this is fine because simple values are passed by value, not by reference. But, when wrapping complex objects in a Signal, the mutability of objects becomes a point of consideration. It's important to understand how the change detection mechanisms in Angular work so that you don't end up falling down the immutability rabbit-hole... read more →
Exploring Lazy Evaluation Of Computed Signals In Angular 18
Yesterday, on Episode 192 of the Working Code podcast, I expressed a fear that the magic of reactivity might lead to unanticipated performance issues when a computed value relies on more than one dependency. But, this fear was purely theoretical. And, it turns out, unwarranted. Computed values in Angular 18 are lazily evaluated. Meaning, they are not computed until they are actually read. And, if they're never read, they're never computed. This post is a small exploration of these Signal timing mechanics in Angular 18... read more →
Building An Angular App For ColdFusion Using Docker Compose
In a world where containerized development exists, I feel like a failure any time I have to run a build script—such as npm install or nvm use—directly on my host computer. Containers should be obviating this type of workflow. But, the problem is, I'm not really that good at containerization. Recently, however, I had a mental breakthrough. I realized that my JavaScript builds didn't have to execute inside my ColdFusion container; instead, I could use a separate Node.js Docker container to perform the build and then output the distribution files to my ColdFusion container... read more →
Working Code Podcast - Episode 192: The Best And Worst Code
On today's show we discuss some of the best code that we've seen and some of the worst code that we've seen. But, "best" and "worst" are fuzzy terms. What does it meant when we even talk about code quality? Does it relate to the maintainability of the code? Does it pertain to revenue generation for the company or how many problems were solved for the customer? Is it about being DRY (Don't Repeat Yourself) or WET (Write Everything Twice) in your intentions? How much does debuggability and logging matter? And, is the best code really just the most boring and predictable code?.. read more →
Working Code Podcast - Episode 191: Too Much Process
People have a lot of trouble existing in the grey. I think we all understand that too much process exists. But, we don't know what to do about it. We have a lot of evidence that in critical arenas—such as medical care and flying planes—that checklists do save lives. But, at the same time, we all believe that spelling corrections on a website don't call for full regression testing. And yet, we do full regression testing anyway. Because, we either don't understand nuance; or, we work at companies that don't allow for human judgement within the decision making framework... read more →
Creating A Transient View Helper In Angular 18
One of the really nice features of Angular 18 is the ability to use a DestroyRef injectable to define your component's clean-up logic. This allows your setup and teardown logic to be collocated within the ngOnInit() life-cycle method. In order for the DestroyRef functionality to work, its own life-cycle has to be married to the host component's life-cycle. Which got me thinking about creating my own transient "View Helper" service that might make other workflows easier... read more →
Working Code Podcast - Episode 190: Career Advice To Younger Self
On today's show, Carol and I reflect on our careers and come up with advice that we'd give to our younger selves. Exercises like this are always a challenge because we have to contend with counterfactuals. That is, we have to either imagine a future that could have been; or, we have to have faith that alternative paths would still have gotten us to where we are today. Neither of these are a certainty... read more →
JavaScript Application Size Shouldn't Affect Performance
I listen to a lot of podcasts in an effort to gain a better perspective on software development. And one sentiment that I've heard repeated a number of times across different podcasts is that as the size of a JavaScript application increases, its performance decreases. This is often touted as a reason to switch from one JavaScript framework to another—that some magical threshold has been reached. But, this sentiment makes little sense. The size of a JavaScript application should be completely disconnected from the performance of said application... read more →
Code Isn't Magical, It's Just A Series Of Commands
For many people, it seems that working on a piece of software is like stepping into the "fog of war". There's a general sense of bewilderment about how any of it works; and a constant fear that even small changes made anywhere might suddenly cause a collapse of the entire system. But this fear is almost always misplaced. It stems from the notion that code is somehow magical. But code isn't magical, it's just a series of commands... read more →
Working Code Podcast - Episode 188: Code Review Nuance
From an academic standpoint, it seems that there should be one unified way in which to review code on an engineering team. A review process has a desired outcome; and, there should be a standard set of steps that help us achieve said outcome. In reality, however, code reviews are heavily nuanced. The depth of effort that we put into a review often depends on the state of the company, the individuals involved, and the type of changes being made within the Pull Request (PR). On today's show, we dig into that nuance; and, try to articulate some of the decisions that we use when we're reviewing other people's code... read more →
An "x-input" Property Binding Directive In Alpine.js
In my previous code kata on building a three-state toggle in Alpine.js, I used the x-effect directive to map outer scope properties onto the inner scope properties of my toggle component. Essentially, every time an outer scope property changed, the reactive aspects of the x-effect directive would turn around invoke my toggle component's reconcile() method, passing-in the updated property values. In other frameworks, this notion of input bindings and life-cycle hooks is more formally codified into the runtime. Taking inspiration from frameworks like Angular, I wanted to see if I could create an x-input directive in Alpine.js that would provide some of this behavior... read more →
Code Kata: Building A Tri-State Switch In Alpine.js
At work, I've been building a bulk-export feature for user prototypes. In the export experience, you can enable and disable "hotspot hinting". But, it's not exactly a binary experience. Meaning, I wanted to include a partially on state in which the hotspot hints were initial invisible; but, which would flash briefly when the user clicked on the prototype screen and failed to make contact with a transparent hotspot. To facilitate this configuration, I created a tri-state switch / toggle component:.. read more →
Using AttributeCollection To Manage Locking In ColdFusion
The other day, when I was demonstrating how to use an ordered struct as a fixed-size cache in ColdFusion, I had to synchronize access to the cache in order to limit the number of cache keys. Whenever I make a new demo, it gives me a chance to reconsider and experiment with different approaches. And, in the aforementioned demo, I used ColdFusion's attributeCollection functionality to define my CFLock tags. This felt like a rather elegant and easily consumable approach; and I wanted to showcase it more directly... read more →
Highlighting Dynamic Parts Of A Pretty-Printed JSON Value In JavaScript
As part of the bulk export functionality that I'm building at work, the user needs to copy-paste a JSON value into an Amazon S3 bucket policy. This bucket policy is generated dynamically, by the app, based on the user's input. And to make the dynamic nature of the JSON value more obvious to the user, I wanted to visually highlight the values driven by the user's input. However, since the JSON payload was being generated by JSON.stringify(), it took me a while to figure out to interleave the value demarcation... read more →
Working Code Podcast - Episode 187: Viability Of The Minimum Viable Product
There's no question that the bar of user experience (UX) has been raised up over the last decade of web application development. With the proliferation of technologies, frameworks, and design systems, developers can now do far more with far less. But, all software has to start somewhere (see John Gall's Law on building complex systems). Which begs the question, what level of fidelity is appropriate for your "v1"?.. read more →
Getting A Struct Key In Its Native Key-Casing In ColdFusion
In ColdFusion, structs are case-insensitive. This is very much a feature of the language, not a bug. But, in some rare edge-cases, I want to validate that the struct key I'm using has the same key-casing that the struct itself is using. There's no native ColdFusion function for this endeavor; so, I created the user defined function, structGetKey()... read more →
OWASP Java Encoder Project Recommends Using Both URL and Attribute Encoding For HREF Attributes
In ColdFusion, whenever I'm constructing a dynamic URL, I always run the dynamic parts through the encodeForUrl() function in order to maintain URL integrity. But, if I then use that dynamic URL to populate an anchor tag's href attribute, I end up operating in nested contexts; and, I'm always left wondering if I should have used the encodeForHtmlAttribute() function instead. For more insight, I went to the OWASP Java Encoder documentation; and, according to their "Common Mistakes" section, I should actually be using both encoding methods... read more →
Normalizing Collection Entries In ColdFusion
In Lucee CFML, looping over collections is effortless because Lucee exposes both the key and value attributes on the CFLoop tag. Furthermore, you can even use struct instead of collection for a more intuitive read on the code. Unfortunately, Adobe ColdFusion hasn't caught up with these ergonomics niceties just yet. As such, I created a user defined function (UDF) that normalizes collections (Structs and Arrays) into an array that always exposes index, key, and value... read more →
Sorting Arrays With Priority Elements In ColdFusion
In the companion app to my feature flags book, I have sample data for deployment environments that contains values such as "Development", "Production", and "Staging". The user can edit this sample data; but, for aesthetic reasons, I always want the collection of environments to be rendered with "Development" in the first index and "Production" in the second index, regardless of what other values the user may add to or remove from the collection. Essentially, I need a way to sort the array of environments where some of the elements are in a fixed, priority location (if they're present at all) and the rest of the elements are sorted alphabetically... read more →
Working Code Podcast - Episode 186: Work Insecurities
On today's show, Carol and I shine a bright light on all of the insecurities that we continue to experience at work despite the fact that we're two high-functioning adults. It seems that no matter how much value we create for our companies—and for our customers—we're always left wondering: Am I doing enough? Am I innovating enough? Am I living up to my job title? Am I having a big enough impact?.. read more →
Creating A ColdFusion-Oriented HashCode With Loose Types (Part 2)
The other day, I looked at creating a HashCode-inspired algorithm for ColdFusion such that you could tell if two different data structures were the same, taking into account ColdFusion's loose type system. Only, once I was done, I realized that it didn't fully serve my purposes. Ultimately, I need it for the companion app to my feature flags book; and, in my companion app, the versioning of configuration data needs to case sensitive for keys. As such, I needed to update my FusionCode.cfc ColdFusion component to allow for two configuration options:.. read more →