Filter an ArrayCollection and don’t lose the original data

by Alberto González on May.02, 2009, under ActionScript, Adobe AIR, Adobe Flex, Coding, Tips & Tricks

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 instanceprivate 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 functionprivate function flashFilter(obj:Object):Boolean{return obj.label.toLowerCase().indexOf("flash") != -1;}//Applying the filterac.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 filterac.filterFunction = flashFilter;ac.refresh();//Test the length property of the ArrayCollectiontrace(ac.length); // 2//Test the source property of the ArrayCollectiontrace(ac.source) // [object Object],[object Object],[object Object],[object Object]//Test the length property of the source propertytrace(ac.source.length) // 4
:, ,

6 Comments for this entry

  • eldervaz

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

  • Nick

    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.

  • Richard Leggett

    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

  • Michael REMY

    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).

  • acnesiac

    I have two dataServices pointing to the same destinationi got two buttons with a binding to the property text with the flag commitRequired for every DSand if i make a change in the list associated to dsCompany , there is a change in dsCompanyTwo.commitRequired too!!why happen this?Best regards

  • AlbertG

    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

*

Looking for something?

Use the form below to search the site:

Still not finding what you're looking for? Drop a comment on a post or contact us so we can take care of it!