How do I append an item to my dataProvider? (Flex) - apache-flex

What I would like to do is simply add to a dataProvider, but when I do, I get an error.
Here's the code I'm trying to run...
dg.dataProvider.addItem(obj.ResultSet.Result[i]);
It's inside a for loop, using i as the integer.
It works great doing...
dg.dataProvider = obj.ResultSet.Result
But that won't work for me, because I need to add to the dataprovider more than once. I'm getting results in batches of 10, and I need to add each batch to the dataProvider when it's received.
I also tried to to do...
var dgDP:dataProvider = new dataProvider();
But for some reason Flex doesn't recognize it...
Any ideas on how I can make this happen?

You have to initialize the dataProvider.
<mx:DataGrid creationComplete="onDGCreate(event)"/>
Script:
public function onDGCreate(e:Event):void
{
var dg:DataGrid = e.currentTarget as DataGrid;
dg.dataProvider = new ArrayCollection();
//or
dg.dataProvider = new XMLListCollection();
}
Now this will work:
dg.dataProvider.addItem(obj.ResultSet.Result[i]);
When you assign something other than ArrayCollection and XMLListCollection to the dataProvider property, it will be converted to an ICollectionView object. The only implementer of this interface is the ListCollectionView class (base class of ArrayCollection and XMLListCollection) which has addItem and addItemAt methods.

A dataProvider is a property which resides on many ListBased classes. It is not a data type. What is the data type of your dataProvider? IT can be XML, an array, an XMLListCollection, an ArrayCollection, an XMLList, or a generic object. [and I assume other data types are supported).
The 'how' you add something to your dataProvider depends entirely on the type of dataProvider you are using.
In Flex 4, the dataProvider objects must implement the IList interface, but in Flex 3 dataProviders are generic objects.
In your situation, since you already have the objects, I'd just loop over them and add them to an array or ArrayCollection and then use hat array as a dataProvider.

Related

Adobe Flex arraycollection

I want to use single collection object to two different UI components. 1. Datagrid and 2nd is chart component. I dont want to change anything inside the arraycollection object but I want to use it at the same time with two different component with minor changes. I know we can use filter function some how but not sure how to apply filter to arraycollection object so that one component (datagrid) can use the original arraycollection object and second component (chart) used the modified one.
Thanks,
If you use the same ArrayCollection as the dataProvider for two different components, then any filter or sort applied to that ArrayCollection will show up in both components.
What you want to do cannot be done.
However, you can create multiple ArrayCollections based on the same source and apply filters to them differently. Conceptually something like this:
public var arrayCollection1 : ArrayCollection = new ArrayCollection();
public var arrayCollection2 : ArrayCollection = new ArrayCollection();
protected function onIGotTheArray(value:Array):void{
arrayCollection1.source = value;
arrayCollection2.source = value;
dataGrid.dataProvider = arrayCollection1;
chart.dataProvider = arrayCollection2;
}
Now you can apply a filter to the first arrayCollection without affecting the second arrayCollection, or vice versa.
This is the preferred approach in my experience.

Setting dataProvider to a comboBox

When setting an arrayCollection as a dataProvider to a comboBox programmatically,if the arrayCollection has just one element,i need to do a small validation:
> public resultHandler(event:ResultEvent):void{
arrColl = event.result.FlexData.ListData as ArrayCollection;
//to check if the arrColl has only one element
if(arrColl == null)
myComboBox.dataProvider = event.result.FlexData.ListData
else
myComboBox.dataProvider = arrColl;
}
I would like to know,if there is a way to skip this validation every time.Is there a way to set dataProvider such that i dont have to check if the collection has one or more elements?
There is no built-in way to do this.
You'll need to either:
create a utility method that does this. For instance
myComboBox.dataProvider = ComboBoxUtil.setDataProvider(collection);
subclass the ComboBox control and override the dataProvider setter where you can include this logic

Alternative to data binding

As an alternative to binding an array collection to a data grid's data provider, could I assign the array collection as the data provider to the data grid on it's creation and everytime the array collection is updated execute invalidateProperties(); invalidateList(); to re-render the data grid?
Does my described approach make sense?
Does my described approach make sense?
Sort of. If you have an arrayCollection ( ac) defined using a get/set method, there is no reason you can't set the dataPRovider on your DataGrid in the set method, every time the data is changed.
If you do that, then you most likely will not have to update the properties or displayList of the DatGrid, because the mere fact of replacing the dataProvider will do it for you.
Something like this:
private var _ac : ArrayCollection;
public function get ac():ArrayCollection){
return this._ac;
}
public function set ac(value:ArrayCollection){
this._ac = value;
this.dataGrid.dataProvider = this.ac;
}
Bingo, every time that the ac value is updated, so will the dataProvider on the DataGrid.

Flex 3 Using an ArrayCollection to Populate Both a Datagrid and a ComboBox

I use this arrayCollection to populate a Flex 3 Datagrid. I'd also like to use this arrayCollection to populate a comboBox with the Name node.
In the arrayCollection, I've got the Name listed twice. I've got two rows in the Datagrid.
If I set the ComboBox's labelfield to Name, then the Name will be listed twice in the ComboBox menu. Is there a way to use this arrayCollection and have each Name listed only once in the comboBox?
I can always make another loop and array collection for the Name, but I was wondering if there were a better way.
var i:uint;
for (i=0; i<myArray.length; i++){
myDGArray = [
{Name: myArray[i].Name, Subject: 'Math:', Pass: myArray[i].math_pass, Fail: myArray[i].math_fail},
{Name: myArray[i].Name, Subject: 'Reading:', Pass: myArray[i].reading_pass, Fail: myArray[i].reading_fail}
]
}
myAC=new ArrayCollection(myDGArray);
Thank you.
-Laxmidi
I'm a bit confused. Based on your code sample, the name will be listed twice in the ComboBox because the same name is used twice in your dataProvider.
You may want o consider converting your dataProvider to two separate ListCollectionView objects, provide different filtering on each object and use those each as se[separate dataProviders.
In psuedo code this is how I'd do it:
public var comboBoxCollection : ListCollectionView = new ListCollectionView(myAC );
public var dataGridCollection : ListCollectionView = new ListCollectionView(myAC );
The apply filtering on the comboBoxCollection to filter out entries with duplicate names. More info on collection filtering in the docs.

flex 3 and autoComplete

im trying to getting auto complete working and i can do so fine when i just create an array in my mxml and then just initialize an arrayCollection at the top of the file in the initialize keyword.
However i want to populate the arraycollection from a webservice but i cant seem to get it;
im my application tag i have the following
creationComplete="init()"
initialize="data2 = new ArrayCollection(data1);"
then in my init method;
private function init():void
{
userRequest.loadWSDL(wsdlUrl);
userRequest.getAllCountries();
}
//this is called when i get a result from userRequest.getAllCountries();
private function getAllCountriesResult(e:ResultEvent):void
{
data1 = new Array(e.result);
}
however my text box is not getting any value.
Anyone with ideas?
first off, Array is not Bindable so changing the variable data1 will have no knock on effect.
The arrayCollection is bindable.
So presumming that the result (e.result) is actually an array (you should check this when debugging) then you could do the following
[Bindable]
priavte var ac : ArrayCollection;
then inside you're getAllCountriesResult function.
ac = new ArrayCollection(e.result);
then anything that has is dataprovider set to the var ac will be updated.
If you wish to update a text value inside a textArea or similar then you should listen for the change event in the arrayCollection and take the appropriate action then.
from your additional points below (just edit your original question)
I take it the autocomplete your talking about is the autocomplete text input box from adobe exchange area as a normal text box doesn’t take an arrayCollection.
If you posted some code it may make it easier to help you.
Preinitialize, then initialize, then creationComplete, then applicationComplete (this is the order they get called in).
If your using the component I’m thinking of, check out http://www.websector.de/blog/2008/04/30/quick-tip-avoid-issues-using-adobes-autocomplete-input-component-using-flex-3/
It appears it may have some issues with flex 3, so check out http://blogs.adobe.com/flex/2006/09/component_autocomplete_text_in.html .
Try this:
private function getAllCountriesResult(e:ResultEvent):void
{
data2.source = new Array(e.result); // or data2.source = e.result as Array
}
Make sure data2 is already initialized as a ArrayCollection.
As for AutoComplete, I'm trying to work things out myself.

Resources