Tappitytap.info

Javascript and values

Objects and properties

When you first start working with javascript within a very short time you will be faced with accessing values from elements on an HTML page. So what to do ?. What is the best approach? and why do there seem to be several ways of doing the same thing?

To access a value from an object is just a simple matter of referring to the property, basically there are 3 ways.
Now each approach has its positives and negatives. not something I'll be looking into here but here are a couple of links with good articles w3schools properties w3docs destructuring if you would like to reasearch a little more.


var obj = {
	prop1: 'data1',
	prop2: 47
};

var result = obj.prop1; // dot syntax
// or
var result = obj['prop1']; // square brackets property access
// or
var {prop1}  = obj; // object destructuring
		

All good, so the next issue is what happens when a property is not set or doesn’t even exist. Not so much of an issue when the creation of the object is in the same section of code as it would probably be very easy to spot, but what happens if this is an object that has been passed to you from another section of code as an argument? .

We now have to start checking things so that our application does not finish up having unexpected behaviours. I always believe that avoiding errors is the better option.

Checking that a property or variable has a value can be done by checking if it is null
we can also check if it exists by checking for undefined


var x;
if (x !== null) alert(x); // the answer in the alert box will be undefined

if(x !== undefined && x !== null) // this statement will aviod accessing a variable that has no value or has not been defined

if(x) alert(x); //this one will check the truthiness of the variable the alert box will not appear

		

In general it would seem that checking for the truthiness of a variable would be a good way to check our variables but it is a very blunt tool and not only undefined and null are checked but also anything that is not considered falsy (false, 0 , -0 , 0n, "", null, undefined and NaN) Truthy MDN Web more than likely 0 and "" are valid values that are perfectly acceptable in your code. So checking for undefined and Null is probably the way to go.

The next thing we should check is that if we are passed an object then we should check that it exists before we try to check the property otherwise this would result in an error.

var obj;

var x = obj.prop1;
	
result set after running script

Oops! not what we want. so even trying to access the property will result in an error even before it's checked as the object has not been initialised.


var obj;

if (obj !== undefined && obj.prop1 !== undefined && obj.prop1 !== null) {
	alert(obj.prop1);
}

//or even additional check for null 

var obj = null;

if (obj !== undefined && obj !== null && obj.prop1 !== undefined && obj.prop1 !== null) {
	alert(obj.prop1);
}
	

And we have to do this for every object and property we encounter -- probably. We could just assume that everything is going to be OK and assuming would save us having to do all the checking and therefor speed things up, that's fine if you can be sure its not going to cause issues in the future , but! there's always a but.


rather than writing the code over and over, then not doing it at all when it all seems too much just put it in a function


function test() {
	var obj = {
		prop1: 'data1',
		prop2: 47
	};

	var val = getVal(obj, 'prop1'); //almost trivial

}

function getVal(obj, prop) {
	return obj !== undefined && obj !== null && obj[prop] !== undefined && obj[prop] !== null ? obj[prop]: null;
}
	

You don't have to do all the checks all the time this could be put into two functions so that we don't keep checking if an object exists all the time when after the first one we already know.

Doing the same for the DOM

When the DOM is queried there is a chance that we may not find anything and so we need the check if something was found.

Using typeof is a good way to check if an item exists its better as it does not throw an error if the variable has not been defined.


var item = document.querySelector('#myitem');
var exists = nullOrUndefined(item);

function nullOrUndefined(item) {
	if (typeof item === "undefined" || item === null) return true;
	return false;
}
	

Once we have found the element that is on the DOM then we can take the information from the element and depending on what type of element it is there are several ways to retrieve the information.


<div>Hello <span>World</span></div>

item.innerText  gets the rendered contents of the element : Hello World
item.innerHtml  gets the html which is contained within : Hello <span>World</span>
item.textContent  gets the contents of all the elements contained within :  Hello World
	

There are different options for different elements, check boxes and radio buttons have a checked property and select lists use a value property. This can add up to a lot of code so having a general function to reliably take the value from the element would simplify the process

using nodeName will tell us what element type we are dealing with and type will tell us the variant so useful in this case for checkbox's and radio buttons. wrap the whole thing in try catch and we have a reliable way to access elements without all the trouble.


function getValue(item) {
	try {
		
		if (nullOrUndefined(item)) throw 'item was null or undefined';

		if (item.nodeName === 'INPUT' && (item.type === 'checkbox' || item.type === 'radio')) {
			return item.checked;
		}
		if (item.nodeName === 'SELECT' || item.nodeName === 'INPUT') {
			return item.value;
		}
		return item.textContent;
	}
	catch (error) {
		throw error;
	}
}
	

Attributes

Do the same for attributes then a couple of functions should do it


function DataAttributeInfo(item, attr) {
	return AttributeInfo(item, 'data-' + attr);
}

function AttributeInfo(item, attr) {
	var result = {
		hasAttrribute: false,
		value: null
	};

	if (nullOrUndefined(item)) throw "object was null or undefined";
	result.hasAttrribute = item.hasAttribute(attr);
	if (result.hasAttrribute) result.value = item.getAttribute(attr);
	
	return result;
}
	

Usage

Checking if objects exist and have a value regardless of the type can be simplified significantly, this keeps your code clean and readable without having to rely on 3rd party frameworks.

The following code sample retrieves a element from the DOM, checks to see that we have found something and then retrieves the value regardless of the type of element. Additionally we retrieve a data attribute all this in 4 lines of code and with all the checking to make sure that we don't have any nasty surprises.


var item = document.querySelector('#myitem');

var val = getValue(item); // get the value

val = DataAttributeInfo(item, 'total'); // get the attribute information
	

Making sure that our code works reliably and does not rely on values always being there is a fundamental part of coding defensively, there are many ways to manage this, checking every value that enters your code from outside is one and may be considered tedious and time consuming but writing a couple of functions to deal with the bulk of the repetitiveness doe’s make the process easier.