Magic Strings – the Anti-Pattern

Having just told you I’ll be writing about design patterns, I’m immediately coming to you with an anti-pattern – the magic string.

A “magic” value in development is a seemingly arbitrary literal value in your code ("eric", 72, "abdc1324") with no explanation as to what the value means. They can be a gigantic code smell

I see magic values all the time in SuiteScript.

Can you spot the magic values here?

Image

The first one is "entity". Now personally, I don’t mind at all using magic strings when specifying field, filter, or column IDs – basically any of the values that come from the NetSuite record/search schema. These are extremely unlikely to change and are generally self-descriptive enough that you’ll know what they mean if you have just a bit of SuiteScript experience under your belt.

But what about "358725"; what the heck is that? Based on the context we can probably reason that it’s the internal ID of an Entity, but which one? We don’t even know which type of entity it is. Customer? Vendor? Contact? Without detailed commenting in every single place this value occurs, we are left clueless, and requiring detailed commenting of simple code like this in multiple places is itself a code smell.

Wherever possible, code should be self-descriptive, not requiring extensive comments to explain. Also, I hope the internal ID of that Entity never changes – say, after a Sandbox refresh. Find/Replace isn’t foolproof.

What if instead, this same condition looked like this:

Image

That should make it pretty obvious – with no comments necessary – exactly which Entity we’re looking for.

What’s probably not obvious is enums. First, it’s the alias I give my enumerations module – a module I create in every single SuiteScript project. More importantly, it’s a great solution for the Magic anti-pattern.

In most languages, an enumeration – “enum” for short – is a really simple data structure that maps a literal value (e.g. "358725") to a programmatic reference (e.g. enums.Vendors.Printful). Unfortunately in JavaScript, we don’t have a formal structure to build enumerations; we have to fake it, but we can fake it pretty easily. The enums module is extremely simple; we return an Object literal with properties as deep as we need to describe the various fixed values (like internal IDs) in our Project:

Image

Now whenever I need the Printful Vendor ID (a pretty common need when you’re building an integration to Printful), I load the enums module and reference enums.Vendors.Printful instead of having to remember and document "358725". Oh and by the way, when we do drop that Sandbox refresh, I have exactly *one* spot in my code to change: the enums module. Everywhere else in the project is using the programmatic reference enums.Vendors.Printful; the only place that needs to change is the literal value "358725".

If I wanted to get super cute, I could even add N/runtime and use it to detect the environment and decide which ID to use, though I generally find this unnecessary. Avoid the environment drift and refresh your Sandboxes regularly!

Save all your magic for solving important problems for your clients/users; use enumerations to replace your magic values.

{"email":"Email address invalid","url":"Website address invalid","required":"Required field missing"}

Related posts

January 7, 2021

Anything I wrote today about business would both feel and be inadequate. I simply can’t arrive at the words to express how I feel in this moment. So instead, here are a few helpful ...

Read More

December 20, 2020

2020 was a hundred swift kicks to the shorts and one giant kick in the ass. If you’ve lost people you love, if you’ve gotten sick or hurt, if you’ve lost your job, if ...

Read More

December 16, 2020

“I’ve been meaning to learn SuiteScript, but it’s hard to find the time …”“We’re slammed, and I just don’t have the time …”“I haven’t made the time …” All are variations of a theme ...

Read More

December 14, 2020

Last week we looked at mimicking the functionality of a REST endpoint with its own module (e.g. retrieving a User, or a list of Users, refreshing a token, etc). For complex integrations that rely on a large ...

Read More