Have you ever had one of those days? I’m not talking about those really bad days when everything seems to go wrong. I’m talking about one of those days where everything is going right and then there’s the one bug that crops up that spoils the streak.
I was having an epic day of code writing. Things were just flowing. I was one with the machine. Then this happened:
TypeError: $(…) is null
I was still in the groove. I thought “no problem, some silly mistake.” After all, this is my day to command my minions of bits. Time passed as I added many console.log statements to verify things were as I thought they should be. All seemed right, yet the javascript error persisted.
Some Background
The page on which this error occurred was a large and complex piece of legacy javascript code (with all of the DOM manipulation that angularjs data bindings would clean up, if the effort could be justified). The page is using jQuery ui. The ugly error started after I added an ajax call to dynamically generate a section of HTML that is added to a jQuery dialog.
Here’s some code that describes the situation:
// Description text section
var descriptionText = item.find(‘div.descriptionText’).html();
console.log("Adding edit contents…");
editContents.append(‘
Description:’ +
‘<textarea style="width: 450px; height: 90px;">’ +</textarea>
<textarea style="width: 450px; height: 90px;"> (descriptionText !== null ? descriptionText : ‘’) +</textarea>
<textarea id="descriptionText" style="width: 450px; height: 90px;"> ‘</textarea>
‘);
// Get the HTML
$.ajax(
{
url: ‘/path/to/getHtml’,
type: "GET",
data: {‘id’: item.attr(‘data-id’)},
async: false,
success: function (data, textStatus, jqXHR) {
console.log("Adding HTML….");
editContents.append(jqXHR.responseText);
}
});
// Now insert the contents into the editDialog, and display it
$(‘#editDialog’).html(editContents).dialog({
width: 500,
height: ‘auto’,
modal: true,
title: "Sample Dialog",
buttons:
{
"Save": function () {
// Save processing
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
The error didn’t make any sense. How could element be null when I was clearly populating it. It turns out that my assumptions about relying on jQuery’s auto open didn’t hold true especially when the HTML contains more than markup. In this case, the HTML returned from the ajax call also contained some dynamically generated javascript code which fired on load.
The crux of the problem
The ajax fetched markup (and script) were loading and the javascript was executing before the DOM element was being added to the page. Major head slap. This meant that $(element) was in fact null. The fix was as simple as moving the population of the HTML to the open event of the jQuery dialog.
// Description text section
var descriptionText = item.find(‘div.descriptionText’).html();
console.log("Adding edit contents…");
editContents.append(‘<p>Description:’ +
‘<textarea id="descriptionText" ‘ +
‘ style="width:450px;height:90px;">’ +
(descriptionText !== null ? descriptionText : ‘’) +
‘</textarea></p>’);
// Now insert the contents into the editDialog, and display it
$(‘#editDialog’).html(editContents).dialog({
width: 500,
height: ‘auto’,
modal: true,
title: "Sample Dialog",
open: function (e) {
console.log("jQuery called this open…");
// Get the HTML
$.ajax(
{
url: ‘/path/to/getHtml’,
type: "GET",
data: {‘id’: item.attr(‘data-id’)},
async: false,
success: function (data, textStatus, jqXHR) {
console.log("Adding HTML…");
editContents.append(jqXHR.responseText);
}
});
},
buttons: {
"Save": function () {
// Save processing
},
Cancel: function () {
$(this).dialog("close");
}
}
});
Putting it together
In hind sight, this example seems so silly, but it points to something much bigger. Writing software isn’t simply some mechanical act. It’s an act of the will that requires the use of intellect combined with the creative and inquisitive nature that all humans possess. I would even say that writing software keeps us humble by reminding us that we are fallible. This notion of being less than perfect is also what keeps us looking for better ways to do things. It drives us to be more creative and to explore new development idioms and techniques. It’s that which fuels our passion to write exceptional code.