Filter an ArrayCollection and don’t lose the original data

By AlbertG on May 2, 2009

Yesterday, one of my students asked me about recovering the original data of an ArrayCollection if this ArrayCollection has a filter applied.

In Adobe Flex, the ArrayCollection class has a property called filterFunction. We can assign a function reference directly to this property and then apply a refresh() to the ArrayCollection instance.
This is an example.


// Defining the ArrayCollection instance
private var ac:ArrayCollection = new ArrayCollection([
           {label:"Adobe Flex", data:"Fx"},
           {label:"Adobe Flash", data:"Fl"},
           {label:"Adobe After Effects", data:"Ae"},
           {label:"Adobe Flash Player", data:"fp"}]);

//Defining the filter function
private function flashFilter(obj:Object):Boolean
{
   return obj.label.toLowerCase().indexOf("flash") != -1;
}

//Applying the filter
ac.filterFunction = flashFilter;
ac.refresh();

Once the filter is applied, the ArrayCollection hides all the objects that don’t pass the validation in the function and shows the objects that do.

An ArrayCollection stores internally an instance of the Array class. You can see that in the previous example where I place an array inside the constructor of the ArrayCollection.

An ArrayCollection acts as a “wrapper” for the array instance enabling functionality that belongs to collections and lists. This functionality can be, filtering, sorting, add/remove/modify data and more.

After you filter an ArrayCollection instance the “wrapper” only shows the unhidden objects and it seems like it only has 2 elements (in my example), I mean if you test the “length” property after the filter you will see that it shows the value 2. But we know the truth, the ArrayCollection actually has 4 elements. If you want to get back this 4 elements without clearing the filter you have to deep into the ArrayCollection and find the source. This source, as I said previously, is an Array.

You will find the source using, in fact, the “source” property of the ArrayCollection. The array that will give you this property is the complete set of data that the ArrayCollection is storing without any filter. Just don’t forget that “source” is giving you an instance of an Array and not an instance of an ArrayCollection.


//continuing the previous example...
//Applying the filter
ac.filterFunction = flashFilter;
ac.refresh();

//Test the length property of the ArrayCollection
trace(ac.length); // 2

//Test the source property of the ArrayCollection
trace(ac.source) // [object Object],[object Object],[object Object],[object Object]

//Test the length property of the source property
trace(ac.source.length) // 4

6 Responses to “Filter an ArrayCollection and don’t lose the original data”

  1. eldervaz says:

    wow, very good Alberto ^^ this is a genial post

  2. Nick says:

    Nice article. I thought I’d add that if you have an ArrayCollection that you want to filter and/or sort without modifying the original ArrayCollection, you can use the ListCollectionView class and modify how you can view that ArrayCollection without modifying the original ArrayCollection or Array.

  3. Also if you are working with ArrayCollections that contain other ArrayCollections (i.e. hierarchical data), you encounter an even trickier situation because you cannot just access the “source” property to get the original data.

    But depending on how you are using the data, there are ways to safely filter nested ArrayCollections without modifying the original source:

    http://richardleggett.co.uk/blog/index.php/2009/05/11/filtering-hierachical-data-in-flex-itree

  4. Michael REMY says:

    nice !

    i spend 3 hours to understand why my original array were not updated while i was apllying a filter on its Arraycollection !

    so it is normal !!!!!!!!!!!!!!!!!!!!!!!!

    for the people like me who want synchronise the Arraycollection and the Array source, you ca do this after the refresh :

    myarray=mycollection.toArray();
    but don’t forget you will lost the orginal value (that what i wanted in my case).

  5. acnesiac says:

    I have two dataServices pointing to the same destination

    i got two buttons with a binding to the property text with the flag commitRequired for every DS

    and if i make a change in the list associated to dsCompany , there is a change in dsCompanyTwo.commitRequired too!!

    why happen this?

    Best regards

  6. AlbertG says:

    Are the 2 DataService instances pointing to the same ArrayCollection instance with the fill method of each one ???

    I mean. How do you fill the elements in each DataService ?? with the fill method ?? and is the fill method using the same ArrayCollection instance ?

Leave a Reply

New releases from ServeBox
Creating a new Twitter client for mobile devices