I am trying to loop through a json result to create a table which I can do fine. The problem I am having is that at the start of the string I have the ‘undefined’ tacked to the start of it and I cant see where it is coming from.
this is my code.
my json result set is: {“errorIsSet”:“1”,“results”:[“The title must not be empty”,“Cost is not correct”]}
var obj = jQuery.parseJSON(data);
if(obj.errorIsSet==1)
{
var i;
var errorImage = '<img src="images/warning.gif" alt="Warning!" width="24" height="24" style="float:left; margin: -5px 10px 0px 0px; " />';
var tableMiddle;
var tableTop = '<table width="100%" border="0" cellspacing="0" cellpadding="0">' ;
for(var i in obj.results)
{
tableMiddle += '<tr><td>'+errorImage+'</td><td>'+obj.results[i]+'</td></tr>';
alert (tableMiddle);
}
var tableBottom = '</table>';
var errorTable = tableTop+tableMiddle+tableBottom;
alert (errorTable);
$("div.error").empty(this).append(errorTable);
$("div.error").show();
}
And this is the resultant html
<table width="100%" border="0" cellspacing="0" cellpadding="0">
undefined<tr><td><img src="images/warning.gif" alt="Warning!" width="24" height="24" style="float:left; margin: -5px 10px 0px 0px; " /></td>
<td>The title must not be empty</td></tr>
<tr><td><img src="images/warning.gif" alt="Warning!" width="24" height="24" style="float:left; margin: -5px 10px 0px 0px; " /></td>
<td>Cost is not correct</td></tr></table>
The issue is that tableMiddle gets declared, but no default value gets assigned to it. Then when you try to add a string to this value, its “value” gets stringified. Of course, right at the start, it isn’t defined (i.e. undefined). Hence you end up with “undefined <tr><td …”
I’ve had quick look at your code and added some comments and small modifications.
/*
Declare all your variables in one place near the top of your current scope.
This will help you keep track of them a lot easier.
JavaScript uses something called "variable hoisting", which effectively
means that any vars you declare in your code, get hoisted up and declared
at the "top" of the current scope.
See [3], [4] and [5] for info about scope
*/
var i = 0,
obj = {},
resultsLength = 0,
errorImage = "",
tableMiddle = "", //the fix for this code was to instantiate tableMiddle as a String
tableTop = "",
errorTable = "";
/*
Note that the above is just a short way to define multiple variables,
you could also do it like this:
var a, b, c, d;
or like this:
var a;
var b;
var c;
*/
obj = jQuery.parseJSON(data);
if( obj.errorIsSet == 1 ) {
errorImage = '<img src="images/warning.gif" alt="Warning!" width="24" height="24" style="float:left; margin: -5px 10px 0px 0px; " />';
tableTop = '<table width="100%" border="0" cellspacing="0" cellpadding="0">';
//getting the length of the results array and caching it
resultsLength = obj.results.length;
//using a regular for loop to iterate over an array
for( i = 0; i < resultsLength; i++ ) {
tableMiddle += '<tr><td>'+errorImage+'</td><td>'+obj.results[i]+'</td></tr>';
/*
I've replaced alerts with console.log() as it doesn't interfere with the flow
of the program (and saves you having to click the dialog boxes ever time).
See Links [1] and [2]
*/
console.log( tableMiddle );
}
tableBottom = '</table>';
errorTable = tableTop+tableMiddle+tableBottom;
console.log( errorTable );
$("div.error").empty(this).append(errorTable);
$("div.error").show();
}