The following code shoud throw an Error #1009: Cannot access a property or method of a null object reference
:
var label:Label;
label.text = value;
However, it doesn't if it's inside of a setter which is set by MXML data binding:
public function set buggySetter(value:String):void {
var label:Label;
label.text = value; //will fail silently
}
To reproduce this weird behaviour, first, create a simple custom component by extending s:Label:
package {
import spark.components.Label;
public class BuggyLabel extends Label {
public function set buggySetter(value:String):void {
var label:Label;
label.text = value; //will fail silently
}
}
}
Sectond, add BuggyLabel to an Application and bind buggySetter:
<fx:Script>
<![CDATA[
[Bindable]
public var foo:String = 'NULL has no properties';
]]>
</fx:Script>
<local:BuggyLabel buggySetter="{foo}"/>
Why does this app fail silently?
The answer to that question is actually fairly short: it's an architectural decision made by the Flex SDK engineers. If you take a look at the Flex source code, you'll see a try ... catch
block swallowing most errors thrown in a Binding.
Pro: makes it easier to use bindings, since you don't have to account for all possible faulty states
Con: it can be harder to debug (though if you know this can happen and you have good unit tests, you can reduce frustration from that side to nearly zero)
The source code I was talking about can be found in mx.binding.Binding
(in the 'framework' project) in method wrapFunctionCall()
. Here's the relevant part:
try {
...
}
catch(error:Error)
{
// Certain errors are normal when executing a srcFunc or destFunc,
// so we swallow them:
// Error #1006: Call attempted on an object that is not a function.
// Error #1009: null has no properties.
// Error #1010: undefined has no properties.
// Error #1055: - has no properties.
// Error #1069: Property - not found on - and there is no default value
// We allow any other errors to be thrown.
if ((error.errorID != 1006) &&
(error.errorID != 1009) &&
(error.errorID != 1010) &&
(error.errorID != 1055) &&
(error.errorID != 1069))
{
throw error;
}
else
{
if (BindingManager.debugDestinationStrings[destString])
{
trace("Binding: destString = " + destString + ", error = " + error);
}
}
}
this Error #1009 is
TypeError: Error #1009: Cannot access a property or method of a null object reference.
in your setter
public function set buggySetter(value:String):void {
var label:Label; // here is the problem
label.text = value; //will fail silently
}
here you are setting text to a lable which is not created....
you are just specify the label var but not created that's why it gives you above Error...
you should either create lable varibal or set data to parent class
your code might be work if...
public function set buggySetter(value:String):void {
var label:Label = new Lable();
label.text = value; //now it ll work
}
or
public function set buggySetter(value:String):void {
this.text = value;
}