I have created a simple method to retrieve XML output from an HTTPService and populate a database from it, but due to the async nature of Flex, the functions go through while its still retrieving data – hence causing the function to return a null value. Please find code below;
View: Declarations
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:dao="database.*"
preinitialize="open_databaseConnection();"
creationComplete="init();"
title="Indexes">
<fx:Declarations>
<dao:IndexesDAO id="srv"/>
</fx:Declarations>
View Functions
private function open_databaseConnection() : void {
indexArrayCollection = new ArrayCollection;
indexArrayCollection = srv.listIndexes();
}
database.IndexesDAO
package database {
import flash.data.SQLConnection;
import flash.data.SQLStatement;
import flash.events.Event;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import models.Index;
import mx.collections.ArrayCollection;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.http.mxml.HTTPService;
import mx.utils.ArrayUtil;
import mx.utils.ObjectProxy;
public class IndexesDAO {
private static var _sqlConnection:SQLConnection;
private var SubSonic:HTTPService = new HTTPService;
public function get sqlConnection() : SQLConnection {
if (_sqlConnection) return _sqlConnection;
var file:File = File.applicationStorageDirectory.resolvePath("db.db");
var fileExists:Boolean = file.exists;
_sqlConnection = new SQLConnection();
_sqlConnection.open(file);
if (!fileExists) {
createDatabase();
get_indexesXML(); //Calls populate database on result event.
}
return _sqlConnection;
}
protected function createDatabase() : void {
var sql:String =
"CREATE TABLE IF NOT EXISTS indexes ( "+
"id VARCHAR(200) PRIMARY KEY, " +
"name VARCHAR(200))";
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = sql;
stmt.execute();
}
protected function get_indexesXML() : void {
var requestString:String;
requestString = "/rest/index.xml";
var requestURL:String = Settings.ServerURL + requestString;
SubSonic.addEventListener(ResultEvent.RESULT, populateDatabase);
auth_send(requestURL);
}
private function auth_send(requestURL:String): void {
SubSonic.url = requestURL;
SubSonic.headers = {Authorization:"Basic " + Settings.EncryptedCreds()};
SubSonic.send();
}
protected function populateDatabase(evt:ResultEvent) : void {
var indexArrayCollection:ArrayCollection = new ArrayCollection();
var length:int;
var i:int;
length = (evt.result['server-response'].indexes.index.source.length);
for (i = 0; i < length; i++) {
var addArray:ArrayCollection;
if (evt.result['server-response'].indexes.index[i].artist is ArrayCollection) {
addArray = evt.result['subsonic-response'].indexes.index[i].artist;
} else if (evt.result['server-response'].indexes.index[i].artist is ObjectProxy) {
addArray = new ArrayCollection(ArrayUtil.toArray(evt.result['server-response'].indexes.index[i].artist));
}
indexArrayCollection.addAll(addArray);
}
var IndexesDAO:IndexesDAO = new IndexesDAO();
for each (var indexArr:Object in indexArrayCollection) {
var index:Index = new Index();
index.id = indexArr.id;
index.name = indexArr.name;
IndexesDAO.create(index);
}
}
public function create(index:Index) : void {
var sql:String = "INSERT INTO indexes (id, name) VALUES (?,?)";
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = sql;
stmt.parameters[0] = index.id;
stmt.parameters[1] = index.name;
stmt.execute();
}
public function listIndexes() : ArrayCollection {
var sql:String = "SELECT * FROM indexes ORDER BY name";
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = sql;
stmt.execute();
var result:Array = stmt.getResult().data;
if (result)
{
var list:ArrayCollection = new ArrayCollection();
for (var i:int=0; i<result.length; i++) {
list.addItem(result[i]);
}
return list;
}
else
{
return null;
}
}
public function refreshIndexes() : ArrayCollection {
var sql:String = "DROP TABLE indexes";
var stmt:SQLStatement = new SQLStatement();
stmt.sqlConnection = sqlConnection;
stmt.text = sql;
stmt.execute();
return listIndexes();
}
}
}
As you can see the view calls
listIndexes();
But it can go through the database population before it can retrieve the result from HTTPService hence producing a null result. Any ideas on how to fix this?
you may want to dispatch an event at the end of
populateDatabaseand run thepart in the eventlistener. then you can be sure that the results are already loaded.