Link to home
Start Free TrialLog in
Avatar of SoLost
SoLostFlag for New Zealand

asked on

How do I convert this code to if-else statements?

I'm trying to modify some javascript written by another developer.  Unfortunately I can't work out the logic.  I was wondering if someone could help me convert this function to if-else statements.

Essentially the code is going through a group of fields and updating the output based on a set of conditions.

Here is the original function:
function (e) {
    o.fields.numberdisplay && (o.fields.numberdisplay.value = "" === e.numberfull ? e.numberdisplay : e.numberfull),
    o.fields.address && (o.fields.address.value = e.displayline),
    o.fields.suburb && (o.fields.suburb.value = "" === e.suburb ? "" === e.mailtown ? e.city : e.mailtown : e.suburb),
    o.fields.city && (o.fields.city.value = "" === e.mailtown ? e.city : e.mailtown),
    o.fields.territory && (o.fields.territory.value = e.territory),
    o.fields.x && (o.fields.x.value = e.x),
    o.fields.y && (o.fields.y.value = e.y),
    o.fields.dpid && (o.fields.dpid.value = e.dpid),
    o.fields.id && (o.fields.id.value = e.id),
    o.fields.postcode && (o.fields.postcode.value = e.postcode),
    o.fields.rdnumber && (o.fields.rdnumber.value = e.rdnumber),
    o.fields.line1 && (o.fields.line1.value = e.address1),
    o.fields.line2 && (o.fields.line2.value = e.address2),
    o.fields.line3 && (o.fields.line3.value = e.address3),
    o.fields.line4 && (o.fields.line4.value = e.address4),
    o.fields.city || !o.fields.suburb || "" !== e.suburb || "" === e.city && "" === e.mailtown || (o.fields.suburb.value = "" === e.mailtown ? e.city : e.mailtown),
    o.fields.address1 && o.fields.address2 ? (e.address4 || 0 === e.address2.indexOf("RD ") ? (o.fields.address1.value = e.address1,
        o.fields.address2.value = e.address2) : (o.fields.address1.value = e.displayline,
            o.fields.address2.value = ""),
        !o.fields.suburb && e.suburb && "" !== e.suburb && ("" !== o.fields.address2.value && (o.fields.address1.value += ", " + o.fields.address2.value),
            o.fields.address2.value = e.suburb)) : o.fields.address1 && !o.fields.address2 && (o.fields.address1.value = e.displayline)
}

Open in new window


And below is what I've hopefully worked out correctly so far (apart from the last ones):
function (e) {
    if (o.fields.numberdisplay) o.fields.numberdisplay.value = e.numberfull === '' ? e.numberdisplay : e.numberfull;
    if (o.fields.address) o.fields.address.value = e.displayline;
    if (o.fields.suburb) o.fields.suburb.value = e.suburb === '' ? e.mailtown === '' ? e.city : e.mailtown : e.suburb;
    if (o.fields.city) o.fields.city.value = e.mailtown === '' ? e.city : e.mailtown;
    if (o.fields.territory) o.fields.territory.value = e.territory;
    if (o.fields.x) o.fields.x.value = e.x;
    if (o.fields.y) o.fields.y.value = e.y;
    if (o.fields.dpid) o.fields.dpid.value = e.dpid;
    if (o.fields.id) o.fields.id.value = e.id;
    if (o.fields.postcode) o.fields.postcode.value = e.postcode;
    if (o.fields.rdnumber) o.fields.rdnumber.value = e.rdnumber;
    if (o.fields.line1) o.fields.line1.value = e.address1;
    if (o.fields.line2) o.fields.line2.value = e.address2;
    if (o.fields.line3) o.fields.line3.value = e.address3;
    if (o.fields.line4) o.fields.line4.value = e.address4;
    
    // These are the ones that I'm unsure of.
    
    o.fields.city || !o.fields.suburb || "" !== e.suburb || "" === e.city && "" === e.mailtown || (o.fields.suburb.value = "" === e.mailtown ? e.city : e.mailtown),
    o.fields.address1 && o.fields.address2 ? (e.address4 || 0 === e.address2.indexOf("RD ") ? (o.fields.address1.value = e.address1,
        o.fields.address2.value = e.address2) : (o.fields.address1.value = e.displayline,
            o.fields.address2.value = ""),
        !o.fields.suburb && e.suburb && "" !== e.suburb && ("" !== o.fields.address2.value && (o.fields.address1.value += ", " + o.fields.address2.value),
            o.fields.address2.value = e.suburb)) : o.fields.address1 && !o.fields.address2 && (o.fields.address1.value = e.displayline)
}

Open in new window

First, can you tell me if I've got the first ones correct, and secondly, help me figure out how to convert the last ones to if-else statements.

Thanks

ASKER CERTIFIED SOLUTION
Avatar of Chris Stanyon
Chris Stanyon
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of SoLost

ASKER

Yes, I am trying to re-write them in a way that I understand.  I was ok until I hit the last couple.  I couldn't quite figure out the logic.  I've never seen it written like that before and it's very hard to understand for someone that's never seen it put like that before.

I do have one question with your solution regarding a particular statement.

You show this as the conversion:

if (!o.fields.suburb && e.suburb && "" !== e.suburb) {
    if ("" !== o.fields.address2.value) {
        o.fields.address1.value += ", " + o.fields.address2.value
    }
    o.fields.address2.value = e.suburb
}

Open in new window


Yet, when I try to follow the logic through, I seem to get a slightly different answer.

if (!o.fields.suburb && e.suburb && "" !== e.suburb) {
    if ("" !== o.fields.address2.value) {
        o.fields.address1.value += ", " + o.fields.address2.value;
        o.fields.address2.value = e.suburb;
    }
}

Open in new window

Can you please explain.

Thanks
Haha - yeah ... definitely complicated to write code like that ... no need really :)

I think it's probably easier to explain if I substitute some variable names, so this:

!o.fields.suburb && e.suburb && "" !== e.suburb && ("" !== o.fields.address2.value && (o.fields.address1.value += ", " + o.fields.address2.value),
    o.fields.address2.value = e.suburb)

Open in new window

Is effectively the same as this:

test1 && test2 && test3 && ( test4 && (var1 = 'match'), var2 = 'match' )

Open in new window

If we work through it, we can come to this:

if (test1 && test2 && test3) {
    test4 && (var1 = 'match')
    var2 = 'match'
}

Open in new window

Inside the if block, we have 2 expressions - the first is another truthiness test, and the second is an assignment, so to expand that out, it becomes:

if (test4) {
    var1 = 'match'
}
var2 = 'match'

Open in new window

Basically, the code you have checks to see if you have a Suburb. If you do, it checks to see if you have an Address2 and appends it to Address1. It then assigns the Suburb to Address2. You end up with Address1 = address1+address2, Address2 = suburb.

As you interpreted the logic, you'd only assign the Suburb to Address2 if you had an Address2 - an empty Address2 and you wouldn't get the Suburb.

Boolean logic can really mess with the head :)
Avatar of SoLost

ASKER

I think I get it now.  Phew!

Thanks for your help!

Avatar of SoLost

ASKER

One last question.  Do you know how to convert the following to an if-else statement?
 
o.fields.city || !o.fields.suburb || "" !== e.suburb || "" === e.city && "" === e.mailtown || (o.fields.suburb.value = "" === e.mailtown ? e.city : e.mailtown)

Open in new window

 
I thought it would be the following:
 
if (o.fields.city || !o.fields.suburb || "" !== e.suburb || ("" === e.city && "" === e.mailtown)) {
    o.fields.suburb.value = "" === e.mailtown ? e.city : e.mailtown;
}

Open in new window

But it throws an error as it goes in there when o.fields.suburb is undefined.

Hmm - as if these logical operators weren't complicated enough, the developer decided to mix and match between || and &&. Ok, let's simplify your code. What you had originally equates to this:

test1 || test2 || test3 || test4 && test5 || (var1 = 'done')

When mixing and matching, the && operator takes precedence over || (similar to how * and / take precedence over + and - in maths!), so we can explicitly represent that like so (notice the paranthesis around test4 && test5):

test1 || test2 || test3 || (test4 && test5) || (var1 = 'done')

Now, another way to think about the operators in a chain is this. You have a series of expressions (test1,test2,test3 etc). The operators tell the code to continue on .... the && operatores will tell it to continue if the previous expression equates to TRUE, and the || operator will tell it to continue on if the previous expression equates to FALSE, so in the code above, if test1 is FALSE, continue. If test2 is FALSE continue etc. If it hits a TRUE, then it stops and won't continue on anymore. So this for example:

test1 || test2 || test3 || alert("We have not values")

We're only going to get the alert if all tests are FALSE. If any are true, the chain breaks and the code doesn't carry on !

So in your code, the final expression will only execute if ALL the previous expressions (4 of them) equate to false:

test1 || test2 || test3 || (test4 && test5)

The thing to realise is that the (test4 && test5) will be tested as 1 expression to see if it's TRUE or FALSE. It will only return TRUE if both test4 && test5 are TRUE. To put it another way, your code will only continue to run if at least one of them is FALSE.

To write this out as a full IF statement, you could end up with something like this:

if (test1 == false && test2 == false && test3 == false) {
    if (test4 == false || test5 == false) {
        var2 = 'done'
    }
}

Open in new window

First we make sure that ALL test1, test2 and test3 expressions are FALSE. If they are, we then check to see if at least one of the test4 and test5 expressions are FALSE.

In your case, you'd end up with something like this:

if (!o.fields.city && o.fields.suburb && "" === e.suburb) {
    if ("" !== e.city || "" !== e.mailtown) {
        if ("" === e.mailtown) {
        	  o.fields.suburb.value = e.city
        } else {
        	  o.fields.suburb.value = e.mailtown
        }
    }
}

Open in new window

Avatar of SoLost

ASKER

Wow, thanks.  I never would have figured that out :)