Link to home
Start Free TrialLog in
Avatar of Bruce Gust
Bruce GustFlag for United States of America

asked on

How would I rewrite this IF statement?

I've got a piece of code that's assuming there is a "length" to a string and then proceeds to make some calculations.

It looks like this:

txn.truncateddescription = (txn.description.length <= 40 ? txn.description : txn.description.substring(0,37) + '...');

The error that I'm getting refers to this line and says, "Cannot read property 'length' of null(…)"

From what I've been able to deduce through resources such as https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator, what I'm looking basically says:

"If the 'description' field is less than or equal to 40 characters, let the 'truncateddescription' value be as it exists in the database. If not, publish it as a truncated string that consists of 37 characters plus "..."

Correct?

How can I adjust it so if the system does encounter a scenario where there are not characters, it simply sets the truncateddescription value as "&nbsp;?"
Avatar of Julian Hansen
Julian Hansen
Flag of South Africa image

The error is saying that you don't have a property called description in txn.

Assuming there was then your understanding is correct.

The code assumes that a description is present but does not say what must happen if it is not there.
Edit
Correction null means description is defined but is set to null.
Avatar of Bruce Gust

ASKER

I smell what you're cooking, Julian!

To explain back to you what you're telling me is that the error is saying I don't have a "description" at all. Now, I know I have a column / value called "description" based on the fact that I have other rows that are being displayed just fine. In this instance, however, "description" is NULL and that's what throwing a wrench in the works.

So...

How do I edit this to accommodate those situations where the description is NULL?

txn.truncateddescription = (txn.description.length <= 40 ? txn.description : txn.description.substring(0,37) + '...');

Could I use this:

if(txn.description=NULL)
{
txn.truncateddescription="";
}
elseif(txn.description.length <= 40
{
txn.truncateddescription= txn.description;
}
else
{
txn.truncateddescription=txn.description.substring(0,37) + '...');
}
you can try:

txn.truncateddescription = ( String( '' + txn.description ).length ) <= 40 ? txn.description : txn.description.substring(0,37) + '...');
How do I edit this to accommodate those situations where the description is NULL
The question is what behaviour do you want when the description is null.

One option is this
// Set description to a valid description or the empty string
// the || (or) will evaluate txn.description and if it equates to a falsy
// value it will do the right bit which is assign the empty string
var description = txn.description || '';

// Once we have a valid string the rest is trivial
txn.truncateddescription = description.length <= 40 
  ? description 
  : description.substring(0,37) + '...';

Open in new window

Big Monty!

I've got a co worker here who's forte is JavaScript and he confirmed that the logic of my IF statement is sound, but I need to build in a dynamic that checks for the "type" of the data. In other words, checking for NULL has to be accompanied by checking the datatype. Forgive me if that sounds wrong, but bottom line: I can't just check for NULL.

That being said, is that what you're doing above? I notice the "String" dynamic preceding the txn.description.length value. Is that what you're doing?
SOLUTION
Avatar of Big Monty
Big Monty
Flag of United States of America 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
checking for NULL has to be accompanied by checking the datatype
??
If it is null - it is null -  the datatype does not come into play
Hence the
var description = txn.description || '';

Open in new window


If txn.description is null, false, 0 or the empty string it will evaluate to false and the right hand side of the or will apply.
Result - description comes out as a string.

The only time this will not work is if txn.description is an object or a function - but you have already stated it comes from your database so I can't see a scenario where that will happen.

In any case neither solution will work if description is not a basic type (number, string).
Consider these examples
<script>
var txn = {
	userid: 1,
	description: {
		value: 'value',
		some: 123
	}
};

txn.truncateddescription = String('' + txn.description);
console.log(txn.truncateddescription);
txn.truncateddescription = txn.description || ''
console.log(txn.truncateddescription);
</script>

Open in new window

Output
[object Object]
Object { value="value",  some=123}

Open in new window


If you really need to check that it is a string then you want to do this
if (typeof txn.description == 'string') {
   txn.truncateddescription =  (txn.description.length <= 40 ? txn.description : txn.description.substring(0,37) + '...');
}
else {
   // handle case when it is not a string
}

Open in new window


EDIT
Important side note - in JavaScript null is considered an object in other words
typeof null === 'object'

Open in new window

Juilan!

I remembered last night the gist of the conversation I had with my counterpart and I wanted to elaborate just so I'm taking full advantage of what it is you're bringing to the table.

It wasn't whether or not the datatype had been defined. The issue was whether or not the value was undefined / uninitialized.

From what I'm attempting to learn, the bottom line is that you cannot expect an accurate result when you check to see if an undefined property equals NULL. Unless the property you're evaluating has been initialized then...

if(uninitialized_property==NULL)
{
not sound syntax at this point because the property hasn't been established
}

I'm going by what I'm reading here, along with the exchange I had with my co-worker.

So, given that context, does that change your recommendation at all?
In answer to your question - consider this code
<script>
var txn = {
	somefield: 123
}
// UNASSIGNED
var result = txn.description || 'defaultvalue';
console.log(result);

// NULL
txn.description = null;
result = txn.description || 'defaultvalue2';
console.log(result);

// EMPTY STRING
txn.description = '';
result = txn.description || 'defaultvalue3';
console.log(result);

// FALSE
txn.description = false;
result = txn.description || 'defaultvalue4';
console.log(result);

// 0 (Zero)
txn.description = 0;
result = txn.description || 'defaultvalue5';
console.log(result);
</script>

Open in new window

Output
defaultvalue
defaultvalue2
defaultvalue3
defaultvalue4
defaultvalue5

Open in new window

As you can see the || assignment results in the defaultvalue string being selected every time. This is because for each of those cases the left hand expression evaluates to false so the defaultvalue assignment is the one that takes.

The point here is that the
var description = txn.description || '';

Open in new window

Will always result in a non-falsy value - undefined / null / false / '' / 0 will all be filtered out in favour of the empty string.
So having done that you know what you are dealing with.

The question is - do you need a clean value or do you need to know what the state of txn.description is.
Light bulb!

First let me explain back to you what you're saying:

In each of the scenarios above, you have a situation where the expression evaluates to a "falsy" value every time. Whether it's undefined, empty, false (Boolean) or zero, it will always "land" as a falsy result.

Correct?

Now, to put a big, fat hairy exclamation point on all this, here's your code, but with my specific quandary included.

If I do this:

<script>
var txn = {
	somefield: 123
}
// UNASSIGNED
var result = txn.description || 'defaultvalue';
console.log(result);

// UNASSIGNED LENGTH
var result_length = txn.description.length;
console.log(result_length);
</script>

Open in new window


I get the very same error that I'm contending with in the app I've been asked to repair.

User generated image
So, it would seem that what I need is to define the state of txn.description before I attempt to ascertain its "length."

If txn.description IS defined, then I proceed to calculate its length and define txn.truncateddescription accordingly
If txn.description IS NOT defined, then I assign "&nbsp;" to txn.truncateddescription and we're all good.

To answer your question, then, I believe the correct response is to say that I need to define its state.

Thanks, Julian!
ASKER CERTIFIED SOLUTION
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
Sweet!

Thanks!

BTW: I still want to understand how NULL can be an object.

I've got that question at https://www.experts-exchange.com/questions/28980256/How-is-NULL-an-Object-in-Javascript.html

Feel free to weigh in.

Thanks, again!
BTW: I still want to understand how NULL can be an object.
It goes back to the very first version of JS - never been changed. Some people call it a bug that was never fixed.