开发者

Search function throwing error #1009 - null object reference

Simple to understand problem, hoping for similarly easy solution:

When I type in my sear开发者_高级运维ch query, I sometimes get the "Error #1009 Cannot access a property or method of a null object reference" on the dataField = new ArrayCollection(result.data); line.

AS3:

        private function getSearch():void
        {
            //status = "Loading data";
            selectStmt = new SQLStatement();
            selectStmt.sqlConnection = conn;
            var sql:String = "SELECT [Index], Title, CAST(Picture AS ByteArray) AS Picture FROM Data WHERE Title LIKE @searchTarget";
            selectStmt.parameters["@searchTarget"] = "%" + searchTarget + "%";  
            selectStmt.text = sql;
            selectStmt.addEventListener(SQLEvent.RESULT, selectResult2);
            selectStmt.addEventListener(SQLErrorEvent.ERROR, selectError);
            selectStmt.execute();
            targetRecordId = pngIndex;
        }

        private function selectResult2(event:SQLEvent):void
        {
            //status = "Data loaded";

            selectStmt.removeEventListener(SQLEvent.RESULT, selectResult);
            selectStmt.removeEventListener(SQLErrorEvent.ERROR, selectError);

            var result:SQLResult = selectStmt.getResult(); 

            dataField = new ArrayCollection(result.data);

            if (result.data != null) {
                pngIndex = result.data.Index;
                pngTitle = result.data.Title;
                pngByteArray = result.data.Picture;
                targetRecordId = pngIndex;
            }
        }

mxml:

<s:List id="myList" 
        x="0" y="40" 
        width="100%" height="100%" 
        labelField="Title" 
        dataProvider="{dataField}"
        change="myList_changeHandler(event)"
        >   
</s:List>

Things I've tried (including the permutations of these solutions):

1) Moving the error code inside the SelectResult2 method

2) Adding an if (result.data == null) method

3) Using Array instead of ArrayCollection (I found someone who found that this worked for their project on some forum somewhere)

4) Adding a timer function to try and limit how often the db will get searched. (although I think this was the best solution, I think I will have to try this one again)

Note, the error occurs, from what I can tell, largely as a result of entering search characters too quickly

Thank you for your help.


1. Use Responders

You're using the same event handler function for each call to the database. Hence when the function gets executed it might have lost the reference to its original statement (because a new call was initiated in the meantime). That's why you get those nullpointers on the result object.

So ditch the event listeners and use a Responder instead, like so:

        var stmt:SQLStatement = new SQLStatement();
        stmt.sqlConnection = connection;
        stmt.text = query;

        var resp:Responder = new Responder(onResult, onFail);
        stmt.execute(-1, resp);

The 'onResult' function will take a SQLResult object as a single argument and you no laonger have to reference the original statement to get that result.

2. Delay

Use a Timer, yes. But don't use it to make the database call on an interval. You wouldn't know when to stop making those calls, would you? Use it to detect whether the user is still typing or not: when it takes longer than - say - 300ms. for one KeyboardEvent.KEY_UP to come after another, then fire the call to the database. Once.

3. Use a threshold

Don't start querying with just one letter. Use a threshold of at least 2-3 characters. You won't get any relevant suggestions with one character anyway. How high the threshold should be, depends on the size of the collection to search.

4. Filter an ArrayCollection

Ignore all of the above. An easier solution might be to just load all the records you want to search into an ArrayCollection and use filterFunction to show only the records that match a certain String. This method will do fine as long as the collection is not gigantic (like tens of thousands of records) and is way faster to implement.


first, how about

if(result == null)
     return;

Also, the timer is a good idea, usually about half a second, that way your database isn't being hammered while the user is typing.

private var timer:Timer = new Timer(500, 1);
protected function textChangeHandler():void{
     timer.reset();
     timer.addEventListener(TimerEvent.Timer, getSearch);//Could be moved to a creation complete
     timer.start();
}

error handle and remove/add events as appropriate. You could also disable the search until the last one has completed, which in combination with the timer shouldn't be intrusive to the user.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜