Flex Datagrids - not for simple arrays

This post is more than 2 years old.

Ok, so time for yet another "duh" moment in my Flex learning. Let me describe the situation I ran into a few days ago. I was working with a ColdFusion Component method that returned an array of objects. This array was being used in a datagrid. So far so good.

One of the things I wanted to do was make it so that when you selected an item from the datagrid, a second datagrid would be populated with a value from the selected item in the first datagrid. My initial array of objects contained a field, typicalsongs, that was also an array.

So here is where things got weird. At runtime when I clicked on an item in the first datagrid, I got the following error:

Variable Typical Song 1 for Station 1 is not defined

So this was really confusing. "Typical Song 1" was the literal first value in the array that should have been loaded into the second datagrid.

It didn't make any sense (and to defend my newbie-status, it confused a few experts as well). While I was trying to figure this out, I reminded myself that I needed to eventually added a DataGridColumn so I can provide a nice label.

Then it hit me. I was trying to load an array of simple values (strings) to the DataGrid. However, DataGrids want arrays of objects. That's where the grid gets the column labels in the first place.

So I'm not sure this is the best solution, but I fixed this in the Flex application. I tend to think I should keep my remote services more generalized and now build them just one for one client. Anyway, I used this code to handle the "rewriting" of the data:

private function loadSongs():void { var currItem:Object = stationlistDG.selectedItem; //The datagrid needs an "object", not a simple list //I'm fixing it here as I feel that the web service is "right" var newSongArray:Array = new Array(); for(var i:int=0; i < currItem.TYPICALSONGS.length; i++) { var newSong:Object = new Object; //matching case of stuff returned from CF newSong.SONG = currItem.TYPICALSONGS[i]; newSongArray[newSongArray.length] = newSong; } songlistDG.dataProvider=newSongArray; }

I could probably do this using the result handler of the initial call. My initial dataset is pretty small (and is guaranteed to be small) so that may make more sense.

Any other opinions?

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Ryan Favro posted on 1/23/2007 at 9:59 PM

Hi Ray,

Wouldn't you want want to return an array of Value Objects paired to flash value objects? Thus avoiding the conversion step in flex?

Comment 2 by Raymond Camden posted on 1/23/2007 at 10:03 PM

I don't use VOs yet. I know I need to. I'm just not there yet in my development. Know what I mean?

Comment 3 by Tom Cornilliac posted on 1/23/2007 at 10:07 PM

I'd create a Station class and a Song class. In the Station class add a public bindable property songList:Array. In your Web Service call result handler I'd loop over the results and create an array of Stations where each Station's songList would hold an array of Song objects.

This feels a little redundant and it's a bit more work up front but (at least to me) it feels cleaner.

Comment 4 by Teddy R Payne posted on 1/23/2007 at 10:21 PM

Why not use drop downs? They are pretty easy to populate.

Cheers,
Teddy

Comment 5 by João Fernandes posted on 1/23/2007 at 10:27 PM

Exactly,

Ray, try to define a list like this

<mx:List dataProvider="{ stationlistDG.selectedItem.TYPICALSONGS }"/>

it should work.

Comment 6 by Raymond Camden posted on 1/23/2007 at 11:38 PM

Um, because I'm an idiot. Thanks for pointing this out. (The list, not the idiot part. ;)

Comment 7 by Bruce posted on 1/24/2007 at 12:06 AM

Ray:

I'm curious about the comment you placed in the code "I'm fixing it here as I feel that the web service is "right"

Why not do the work of creating an Array of Song objects for each Station object in the CFC? I know that if you create a large number (hundreds) of objects in CF and pass that many to Flex there can be a time drag, but you state your dataset is guaranteed to be small.

By leveraging the power of the CFC, your Flex code would be much cleaner. Also if you wanted to expand in the future what information you include about the station's typical songs (song artist, song genre, etc) you can easily do that in the CFC and not have to change much in the Flex code (except how you display the additional data).

Anyway, perhaps I'm not following your logic for doing the work of creating the Array of Song objects in Flex instead of in the CFC.