Person field comes back "undefined"

Feb 1, 2012 at 9:58 PM

I am pulling data from a list and populating an array like this: 

$().SPServices({
      		operation: "GetListItems",
      		async: false,
      		listName: "Project Index",
      		CAMLViewFields: "<ViewFields><FieldRef Name='ESP' /><FieldRef Name='ESP_thru_FY' /><FieldRef Name='Title' /><FieldRef Name='Test Manager' /><FieldRef Name='Project Title' /><FieldRef Name='ID' /></ViewFields>",
		CAMLQuery: "<Query><OrderBy><FieldRef Name='ESP' /></OrderBy></Query>",
		completefunc: function (xData, Status) 
				{
				$(xData.responseXML).find("[nodeName='z:row']").each(function()
					{
					txtESP = $(this).attr('ows_ESP');
					txtESPthru = $(this).attr('ows_ESP_thru_FY');
					if (txtESP !=null)
						{
						if (txtESPthru !=null)
							{
							aryProjESP[aryProjESP.length] = {ESP: $(this).attr('ows_ESP'), ESPthru: $(this).attr('ows_ESP_thru_FY'), PID: $(this).attr('ows_Title'), TTL: $(this).attr('ows_Project_x0020_Title'), ID: $(this).attr('ows_ID'), TM: $(this).attr('ows_Test_x0020_Manager') };
							}
						}
					});
				}
		  	});
Now, when I go to write the TM variable ("Test Manager" value) into a table, it writes "undefined" instead of the 
person name (which I know is populated in the list). 
Here is where I am building the table string: 
tblstr += " (" + aryProjESP[s].TM + ")";
...And the outcome on the page is "(undefined)".  What gives?  I expected: "1#LName, FName etc" 
Thanks,
Don
Feb 2, 2012 at 12:51 AM

I'm guessing it has something to do with how you are adding objects to your array.  You probably should use an object here to get around any weird array bugs.  Here's something to get you started:

var yourObj = {};

$().SPServices({
	operation: "GetListItems",
	async: false,
	listName: "Project Index",
	CAMLViewFields: "<ViewFields><FieldRef Name='ESP' /><FieldRef Name='ESP_thru_FY' /><FieldRef Name='Title' /><FieldRef Name='Test Manager' /><FieldRef Name='Project Title' /><FieldRef Name='ID' /></ViewFields>",
	CAMLQuery: "<Query><OrderBy><FieldRef Name='ESP' /></OrderBy></Query>",
	completefunc: function (xData, Status) {
		$(xData.responseXML).find("[nodeName='z:row']").each(function( idx, el ) {
			var $node = $(this),
				id = $node.attr('ows_ID'),
				txtESP = $node.attr('ows_ESP'),
				txtESPthru = $node.attr('ows_ESP_thru_FY');
				
			if ( txtESP != null ) {
				if ( txtESPthru !=null ) {
					yourObj[ id ] = {
						ESP: $node.attr('ows_ESP'), 
						ESPthru: $node.attr('ows_ESP_thru_FY'), 
						PID: $node.attr('ows_Title'), 
						TTL: $node.attr('ows_Project_x0020_Title'), 
						ID: id, 
						TM: $node.attr('ows_Test_x0020_Manager') 
					};
					//Uncomment to view the properties of yourObj
					//console.dir( yourObj[ id ] );
				}
			}
		});
	}
});

 

OR... You can change how you are stuffing your array and use .push();

$().SPServices({
	operation: "GetListItems",
	async: false,
	listName: "Project Index",
	CAMLViewFields: "<ViewFields><FieldRef Name='ESP' /><FieldRef Name='ESP_thru_FY' /><FieldRef Name='Title' /><FieldRef Name='Test Manager' /><FieldRef Name='Project Title' /><FieldRef Name='ID' /></ViewFields>",
	CAMLQuery: "<Query><OrderBy><FieldRef Name='ESP' /></OrderBy></Query>",
	completefunc: function (xData, Status) {
		$(xData.responseXML).find("[nodeName='z:row']").each(function( idx, el ) {
			var $node = $(this),
				id = $node.attr('ows_ID'),
				txtESP = $node.attr('ows_ESP'),
				txtESPthru = $node.attr('ows_ESP_thru_FY');
				
			if ( txtESP != null ) {
				if ( txtESPthru !=null ) {
					aryProjESP.push({
						ESP: $node.attr('ows_ESP'), 
						ESPthru: $node.attr('ows_ESP_thru_FY'), 
						PID: $node.attr('ows_Title'), 
						TTL: $node.attr('ows_Project_x0020_Title'), 
						ID: id, 
						TM: $node.attr('ows_Test_x0020_Manager') 
					});
				}
			}
		});
	}
});

I would recommend using the first example though. From what I've gathered from the interwebz, it's a cleaner solution and will keep you from weird things happening when using arrays as hash tables.  If you were using aryProjESP.length simply to increment, then .push() should work well for you.

Let me know if that helps!

Cheers,

Matt

Feb 2, 2012 at 1:31 AM

Thanks for that, Matt. 

It seems I made a pig's ear out of the "insert code snippet" functionality...sorry!

Yes, was using the array length to increment new values into the array. 

I see some curiosities in your "push" code:

			var $node = $(this),
				id = $node.attr('ows_ID'), //*********Did you mean to put commas here????
				txtESP = $node.attr('ows_ESP'),
				txtESPthru = $node.attr('ows_ESP_thru_FY');

 

$(xData.responseXML).find("[nodeName='z:row']").each(function( idx, el ) { //****what is the meaning of the "idx, el"???

 

I am pulling about 78 projects into the array.  Will your push method index the projects?  i.e., aryProjESP[x].ESP would be different from aryProjESP[y].ESP? 

Thanks Again!

Don

 

Feb 2, 2012 at 1:33 AM

Incidentally, all the other (text) values  in the hash array worked fine.  It was just the person data type (evidently a lookup, right?) that came up undefined. 

Feb 2, 2012 at 1:52 AM
Edited Feb 2, 2012 at 2:00 AM

Are you sure your <ViewFields> are correct?  If there is a space in the Static Name, then it should be: Test_x0020_Manager.  Same goes for Project_x0020_Title.  This could be the issue altogether. :)

 

Now to answer your q's:

			var $node = $(this),
				id = $node.attr('ows_ID'), //*********Did you mean to put commas here????
				txtESP = $node.attr('ows_ESP'),
				txtESPthru = $node.attr('ows_ESP_thru_FY');
Yes, I meant to put commas.  This is an optimization technique when declaring multiple variables.  Instead of typing var over and over again, a simple comma allows you to create a new local variable on the fly.  id, txtESP, txtESPthru are all still local variables.  The reason I do this is for minification purposes.  If your minifier takes care of this for you already, then it doesn't matter.


$(xData.responseXML).find("[nodeName='z:row']").each(function( idx, el ) { //****what is the meaning of the "idx, el"???
These two parameters are native to jQuery's .each() function (you get them for free).  They are always there, but you have to add the reference to your function. 99% of the time, I put them on my .each() calls, just to be consistent regardless if I use them or not.  Here's some more info on .each().

Cheers,
Matt
Feb 2, 2012 at 12:11 PM

Matt, Thanks again!

re: Commas--  I didn't look at it right first time.  I am kinda new to JS, but I recognize that form from other languages (vb, etc). 

I have not been putting the x_0020_ in the view fields.  The Project Title pulls just fine...however, I will try that.

I'll also read up on the each function.

Have a great day!  

Don

Feb 2, 2012 at 1:14 PM

I just got it working.  The only thing I changed was to add the _x0020_ to the field ref name for the people column.  Now on to parsing out the ID# on the name. 

Many Thanks!

Don