Building strings with conditions

TLDR: On my current project the BA's want everything written out in English sentences, yep that's just the way it is (OK not everything). Just when the wind blows, I can't say I agree. Showing Data vs Making Readable strings

An example

Sometimes it's better the be explicit, with the possible outcomes of a function. Multiple returns allow us to see that very clearly. Or is this a case statement in hiding?

function getAccountAwardStatus() {
    const customerAccount = {
        "date_of_birth": "12/12/2000",
        "date_of_birth_registered" : "13/12/2022",
        "date_of_birth_at_hospital" : "12//3/3333"
    }

    if (doesNotHaveAnAward(customerAccount))
        return "no amount"

    if (doesNotHaveCurrentAward(customerAccount))
        return "no current award"

    if (hasAwardAmount(customerAccount))
        return `Current award of ${getAmount(customerAccount)} was closed on ${getClosedDate(customerAccount)}`

    if (hasClosingDate(customerAccount))
        return "Current award was closed on 12 January 2000"

    return "no award status";
}

How this normally works

When showing data from say a record, normally you would just show the data field names and then the data right? Let's see how that looks :

Date Of Birth    : 12/12/2000
Account Type      : Current
Award Amount     : £40.00
Award End Date   : -

You get the idea, field names and data values, in a clear simple format. If there is no data then well, you would normally just leave it blank, or put a dash (for them with bad eye-sight!)

We want a English sentences

Now then our BA's love to spend money on useless features 😂, and one of them is the use of proper English sentences. Now don't get me wrong, if I was sending out a letter to a customer you might want to try and write a sentence and include the data some how, but then again, when I look at my utility bills even they don't attempt to do that.

So what is the problem

Creating a sentence from data can be difficult and costly, it's cheap to show data with the name of and the field, then just an empty line if it's empty.

Which reminds me, never hide data field names, where it's empty, that really is just silly.

And now the example in full

Have you ever found yourself, building up the content of a string, based on some object literal?

OK, here is an example, this is infarct a real example, I'm trying to build a string and there are 4 possible outputs.

"No awards" "No current awards" "Account of £3.000 was closed on 12 January 2000." "Account was closed on 12 January 2000." "Account was closed on 10 January 2000."

Now where things start getting interesting, the value £3,000, is not in the format we want!

The amount value could also be in two different places within the entity, depending on the type of account.

Yeah, you might be thinking the same thing I was, the entity is just plain garbage, and that the data is just badly designed, and you are right. But this is what I have to deal with.

When it come to this kind of problem of creating strings based of business logic, I've seen developers fall down every time. What do I mean? Well, they start writing spaghetti code, mind bending garbage that can't be understood withing putting some brain power into the task!

So first the solution, when you have 4 conditions, with 4 outputs keep then separated.

I've also found that the "one return rule" that I've seen so many developer do, it forcing developers to write really bad code again. The "one return rule" is a code smell. I you want your code to be readable then just stop that now get some help.

This my friend is the "clean/readable" way to write this code, the alternative is not.

It's better to be explicit, write the code out in full. Don't go down the if-else route.

A few things to note, we could wrap the customerAccount, to make it more useful.

That would allow use to wrap the data into a object with methods that we can use, it gives us something a little better.

This is more encapsulation, and I think this works really well, we should do that.

It's a new object that wraps the value, is it a Functor, nope. but the same sort of thing.

..and now the wrong way 😱

psssst, wanna see some code………