undefined method in object? - actionscript-3

I get an error when I want to compile the following code...
I get undefined method when I'm trying to set a variable with the Filters class..
trace(filters.txt()); // returns undefined method
trace(filters); // returns [object Filters]
but I'm using this same object in other scripts without problems?
package player {
import flash.display.Sprite;
import filters.Filters;
public class Time_bar extends Sprite {
private var bar = null;
public var color = null;
public var _w = 0;
public var _h = 0;
public var _x = 0;
public var _y = 0;
public function Time_bar(){
this.bar = new Sprite();
addChild(this.bar);
}
public function cnstr(){
this.bar.graphics.beginFill('0x'+this.color);
this.bar.graphics.drawRect(0, 0, this._w, this._h);
this.bar.graphics.endFill();
this.bar.x = this._x;
this.bar.y = this._y;
this.bar.alpha = 0.75;
this.bar.scaleX = 0;
var filters = new Filters();
trace(filters);
trace(filters.txt());
//filters.txt(this.bar);
}
public function progress(float){
this.bar.scaleX = float;
}
}
}
the Filters class looks like this:
package filters {
import flash.display.Sprite;
import filters.Filters_glow;
public class Filters extends Sprite {
private var Glow = new Filters_glow();
public function txt(instance){
Glow.color = '93fafe';
instance.filters = [Glow.filter()];
}
public function loader(instance){
Glow.color = '93fafe';
Glow.alpha = 0.5;
instance.filters = [Glow.filter()];
}
}
}
Filter_glow:
package filters {
import flash.filters.GlowFilter;
public class Filters_glow {
public var color = '000000';
public var alpha = 0.25; // range: 0-1
public var blurX = 4; // range: 0-255; optimized values: 2,4,8,16 etc
public var blurY = 4; // range: 0-255; optimized values: 2,4,8,16 etc
public var strength = 1; // range: 0-255
public var quality = 3; // range: 0-15
public var inner = false;
public var knockout = false;
public function filter(){
this.color = '0x'+this.color;
return new GlowFilter(this.color, this.alpha, this.blurX, this.blurY, this.strength, this.quality, this.inner, this.knockout);
}
}
}

var _filters = new Filters();
_filters.txt(this.bar);
aparently filters is a reserved property name.. after changing filters to _filters the error disapeared :)

To verify whether the method "txt" exists on the filters object you'd have to write trace(filters.txt);. Instead you're executing the txt-method with a missing parameter by adding the brackets. And while executing, it tries to access instance which is undefined. I agree with Matti though that the error message should say something else.
As to why filters.txt(this.bar); doesn't work, I suspect the problem lies elsewhere, can you include the invoking code and the Filters_glow class?

The error is clearly visible. You are not passing the only required argument to the function txt.
public function txt(instance){
Glow.color = '93fafe';
instance.filters = [Glow.filter()];
}
So you can only call txt function by passing it an instance even. something like:
trace(filters.txt(YourObject));
I assume the argument is an instance of the object you want to apply the filter to or something like that. Well it's your function...

try modifying your code as follows, this might help with the error:
//...
public class Filters extends Sprite {
private var Glow: Filters_glow;
public function Filters(){
Glow = new Filters_glow();
}
public function txt(instance: DisplayObject = null): Boolean{
if(!instance){
return false;
}
Glow.color = '93fafe';
instance.filters = [Glow.filter()];
return true;
}
//...

Related

Flex - Problems in accessing static variable on another mxml page

First.mxml - Contains a Datefield control as follows:
<mx:DateField id="G2_CRTLoadDate" width="150" selectedDate="{modelProxy.G2_CRTLoadDate}" change="{modelProxy.G2_CRTLoadDate = event.currentTarget.selectedDate;changeManagerStatus()}"/>
I'm assigning this Datefield value to a static variable CERT_LOAD_DATE as follows(First.mxml):
[Bindable]
public static var CERT_LOAD_DATE:String = "";
private function changeManagerStatus():void
{
CERT_LOAD_DATE = G2_CRTLoadDate.selectedDate.toDateString();
}
Second.mxml -Here, I have a Combobox as follows:
<mx:ComboBox id="General_Release_Dates"
selectedItem="{modelProxy.General_Release_Dates}"
valueCommit="{model.General_Release_Dates = event.currentTarget.selectedItem;updateReleaseDate(event)}"
change="{model.General_Release_Dates = event.currentTarget.selectedItem;updateReleaseDate(event)}" close="closeHandler(event);" includeInLayout="true" visible="true">
</mx:ComboBox>
Inside the closeHandler function, I'm trying to access the variable CERT_LOAD_DATE as follows:
private function closeHandler(evt:DropdownEvent):void {
var CurrentDate:Date = new Date();
if(General_Release_Dates.selectedLabel.toString() == "TBD")
{
Alert.show(First.CERT_LOAD_DATE);
}
}
The alert box displays no value (null). Please help.
I can't figure out the relationship between First.mxml and Second.mxml from your question.
However, the following code can't access First.mxml.
Alert.show(First.CERT_LOAD_DATE);
Because the "First" is not the same instance as loaded "First.mxml".
How about to use singleton? It's accessible from anywhere.
1st, add MySingleton.as class like this.
package foo.bar
{
public class MySingleton
{
private var _cert_load_date:String;
public function MySingleton(internally:SingletonInternal)
{
super();
if(internally == null)
{
throw new Error("Please use getInstance() method.");
}
}
public static function getInstance():MySingleton
{
return SingletonInternal.instance;
}
public function set cert_load_date(value:String):void
{
_cert_load_date = value;
}
public function get cert_load_date():String
{
return _cert_load_date;
}
}
}
import foo.bar.MySingleton;
class SingletonInternal{
public static var instance:MySingleton
= new MySingleton(new SingletonInternal());
public function SingletonInternal(){}
}
How to use
Set value at First.mxml.
public var singleton: MySingleton = MySingleton.getInstance();
private function changeManagerStatus():void
{
singleton.cert_load_date = G2_CRTLoadDate.selectedDate.toDateString();
}
Second.mxml
public var singleton: MySingleton = MySingleton.getInstance();
private function closeHandler(evt:DropdownEvent):void {
var CurrentDate:Date = new Date();
if(General_Release_Dates.selectedLabel.toString() == "TBD")
{
Alert.show(singleton.cert_load_date);
}
}
Updated: Aug 27 10:00(JST)
I think there are two way to change First.mxml's element using singleton.
1) Binding the DateField value to singleton variables, and clear the value at Secend.mxml.
2) Assign to singleton variables whole "First", and control from Second.mxml.
I'll write here the 2nd way.
If you use this way, anything is controlable from Second.mxml.
MySingleton.as
private var _first:Object;
public function set first(value:Object):void
{
_first = value;
}
public function get first():Object
{
return _first;
}
First.mxml
singleton.first = this;
Second.mxml
public function something(): void{
First(singleton.first).G2_CRTLoadDate.selectedDate = null;
// The cast is unnecessary. Following code also works.
// singleton.first.G2_CRTLoadDate.selectedDate = null;
}
Also you can execute First.mxml's public function from Second.mxml.
singleton.first.someFunctionDefinedAtFirst();

AS3 Can't get array from another class

Well, I have a problem, with searching changes of array in ItemProperty class. When i calling to trace item array length, than it gets 0. But in ItemProperty class only in RecieveIndex function item length getting more than 2. Even ReturnData() got 0. The question is how to get final result of this array(Item) in InventoryData class?
That is class, when i got 0:
public class InventoryData extends Sprite {
private var item:ItemProperty = new ItemProperty();
public function InventoryData(){
trace(item.Item);
trace(item.Item.length);
//trace(item.ReturnData());
}
}
Class where array was formed. In RecieveIndex method Item length more than 0.
public class ItemProperty extends Sprite{
public var Item:Array = [];
public function ItemProperty() {
var connect:Connection = new Connection();
connect.setRequest("Select", "`inventory`", ["all"], ["all"], InventoryContent);
}
private function InventoryContent(RecieveData:Array):void
{
var picking:Connection = new Connection();
picking.setRequest("Select","`weapon`",["all"],["id IN("+RecieveData[0].contents.toString() + ")"], InventotyData);
}
private function InventotyData(RecieveData:Array):void{
var indexdecode:Connection = new Connection();
for(var i:uint=0; i<RecieveData.length; i++)
{
indexdecode.loadImageFromBase64(RecieveData[i].id, RecieveIndex);
}
}
public function RecieveIndex(index:int):void {Item.push(index); }
public function ReturnData():Array {return Item;}
}
Something like this with the event I mentioned in my comment:
public class InventoryData extends Sprite {
private var item:ItemProperty = new ItemProperty();
public function InventoryData(){
item.addEventListener(ItemProperty.ARRAY_READY, onArrayReady);
}
private function onArrayReady(e:Event):void {
trace(item.Item.length);
}
}
In ItemProperty class you declare a new constant:
public static const ARRAY_READY:String = "arrayReady";
and once you have the array filled with the items you want to retrieve, you add:
dispatchEvent(new Event(ARRAY_READY));

use of addChild inside a function to add a child into a previously added instance

I wrote a simple function "adone" to add things to the stage and today I decided to make it add child to other objects as well but the test function "ad2" I made is not working right. what do you suggest?
package {
import flash.display.MovieClip;
public class main extends MovieClip {
public var ui:Array = new Array;
public var splz:Array = new Array;
public var pows:powsys = adone("powsz",powsys,ui,400,240);
public var s1:powsyspsl = ad2("s1",powsyspsl,splz,100,100,"powsz");
public function main() {
}
public function adone(nm,tp,lst,ex=0,ey=0) {
nm = new tp();
addChild(nm);
lst.push(nm);
nm.x = ex;
nm.y = ey;
}
public function ad2(nm,tp,lst,ex=0,ey=0,par=null) {
nm = new tp();
par.addChild(nm);
lst.push(nm);
nm.x = ex;
nm.y = ey;
}
}
}
public var pows:powsys = adone("powsz",powsys,ui,400,240);
you are setting first parameter "powsz" but you're not using this parameter, you're just changing it with nm = new tp(); when your adone() function worked, so it is looking like working properly...
and here...
public var s1:powsyspsl = ad2("s1",powsyspsl,splz,100,100,"powsz");
you're not making the same fault as in "adone()" so it is still a string variable and you're trying to add a child to a string variable "powsz" here? i think you should fix that
par.addChild(nm);
but if you don't wanna fix things but you wanna your code work unproperly you can try this
public function ad2(nm,tp,lst,ex=0,ey=0,par=null) {
nm = new tp();
par = new tp();
par.addChild(nm);
lst.push(nm);
nm.x = ex;
nm.y = ey;
}
And all this stuff looks like a joke! Your problems not going to be solved by this way, you have to fix your whole code and logic.. You're using lots of unnecessary stuff and wrong ways to make what you want...
changed the code to:
package {
import flash.display.MovieClip;
public class main extends MovieClip {
public var ui:Array = new Array ;
public var splz:Array = new Array ;
public var pows:powsys = adone("pows",powsys,ui,400,240);
public var s1:powsyspsl = adone("s1",powsyspsl,splz,100,100,pows);
public function main() {
}
public function adone(nm,tp,lst,ex=0,ey=0,par=null) {
nm = new tp ;
if (par) {
par.addChild(nm);
} else {
addChild(nm);
}
lst.push(nm);
nm.x = ex;
nm.y = ey;
}
}
}
the "par" var returns null both times in the trace. and that means 2nd object is added to the stage not to 1st one.
Untested....
package {
import flash.display.MovieClip;
public class main extends MovieClip {
public var ui:Array = new Array;
public var splz:Array = new Array;
public var pows:powsys = adone(powsys,ui,400,240);
public var s1:powsyspsl = adone(powsyspsl,ui,400,240,pows);
public function main() {
}
public function adone(tp,lst,ex=0,ey=0,par=null):Object {
var nm = new tp();
if (par) {
par.addChild(nm);
} else {
addChild(nm);
}
lst.push(nm);
nm.x = ex;
nm.y = ey;
return nm;
}
}
}

how to convert string to object name. as3

public class ColorLibrary {
private var _allColorCodes:Object;
public function ColorLibrary() {
init();
}
private function init(){
_allColorCodes = {
'black' : '000000',
'white' : 'FFFFFF',
'yellow' : '000000'
}
}
public function exchangeColor(colors:String){
var colorArray:Array = colors.split(',');
for ( var i:int = 0; i < colorArray.length; i++ ) {
_allColorCodes.getDefinitionByName(colorArray[i]);
}
}
}
any idea how to convert string to instance name? Thanks very much~! Strugglying here
You've already got an object there, so you can already go:
_allColorCodes.black .. etc
Considering that _allColorCodes is private, you can do a really nice little getter like so:
public function get colorCode():Object
{
return _allColorCodes;
}
And then just have:
trace(colorCode.black);
trace(colorCode.yellow);
All that said, what I would do is store all this stuff against constants in a class like ColorCodes, like this:
package
{
public class ColorCodes
{
public static const BLACK:uint = 0x000000;
public static const RED:uint = 0xFF0000;
public static const BLUE:uint = 0x0000FF;
public static const GREEN:uint = 0x00FF00;
public static const WHITE:uint = 0xFFFFFF;
}
}
And then access them via:
trace(
ColorCodes.RED
);
Something slightly more advanced that you can do is make use of Proxy and flash_proxy to override the getProperty() method. This means you'll be able to go ColorLibrary.color straight off the bat:
package
{
import flash.utils.Proxy;
import flash.utils.flash_proxy;
public class ColorLibrary
{
private var _allColorCodes:Object;
public function ColorLibrary()
{
_allColorCodes = {
'black' : '000000',
'white' : 'FFFFFF',
'yellow' : '000000'
}
}
override flash_proxy function getProperty(name:*)*
{
return _allColorCodes[name];
}
}
}
Response to comment:
Okay, you don't need to use getDefinitionByName here, you can simply use brackets to access a value of an object by parsing a string.
Example:
var object:Object = {
something: 2,
anotherThing: "something awesome"
};
trace(object["something"]); // same as object.something
trace(object["anotherThing"]); // same as object.anotherThing
Try something like this for your exchangeColor() function:
public function exchangeColor(colors:String):void
{
var colorArray:Array = colors.split(',');
for each(var i:String in colorArray)
{
trace(
_allColorCodes[i]
);
}
}
I canĀ“t see why you would want to do it like this, but here is a function that passes a list of colors (String) and returns hex codes (Array). If one color does not exist you will get lost in the Array. I Recommend using ColorList.RED or at least ColorManager.getColor("red").
var colorList : Array = getColorList("black,yellow");
public function getColorList(colors : String) : Array
{
var result : Array = new Array();
var colorArray : Array = colors.split(',');
for(var i : int = 0; i < colorArray.length ; i++)
{
if(_allColorCodes[colorArray[i]])
result.push(_allColorCodes[colorArray[i]]);
}
return result;
}

In ActionScript 3, tracing all properties of a value object

I have a number of value objects and I want to be able to create a function within it to trace out the properties and the values without specifying them directly. It will allow me to use the same code in all value objects as opposed to referring to variables within the value object. Ideally, I would like to replace the code in blogURLVars with this code.
Here's a sample value object
package items {
public class Blog {
private var _itemID:uint;
private var _blogTitle:String;
private var _blogText:String;
private var _blogCreated:String;
private var _blogCategory:String;
private var _blogFrontpage:Boolean;
public function Blog (itemID:uint,blogTitle:String,blogText:String,blogCategory:String,blogCreated:String,blogFrontpage:Boolean=false) {
_itemID = itemID;
_blogTitle = blogTitle;
_blogText = blogText;
_blogCreated = blogCreated;
_blogCategory = blogCategory;
_blogFrontpage = blogFrontpage;
}
public function get itemID():uint {
return _itemID;
}
public function get blogTitle():String {
return _blogTitle;
}
public function get blogText():String {
return _blogText;
}
public function get blogCategory():String {
return _blogCategory;
}
public function get blogCreated():String {
return _blogCreated;
}
public function get blogFrontpage():Boolean {
return _blogFrontpage;
}
public function toString():void {
}
public function blogURLVars():String {
var s:String;
s = "itemID="+ _itemID;
s += "blogTitle="+ _blogTitle;
s += "blogText="+ _blogText;
s += "blogCategory="+ _blogCategory;
s += "blogCreated="+ _blogCreated;
s += "blogFrontpage="+ _blogFrontpage;
return s;
}
}
}
DescrybeType could be of help here. I'm basing this answer in this other answer (you might want to check it out): Fastest way to get an Objects values in as3
Basically, the describeType function will let you inspect the public interface of your object. That means public variables, getter/setters and methods (plus some other info not relevant to your problem). So you get a list of all the getters and with that, return the names of said properties plus their actual values for a given object. Not that this is not exactly the same as your sample code, since this will not use the private variables, but rather will call the getters.
In code, this could be something like this (based on code in the linked question).
package {
import flash.net.URLVariables;
import flash.utils.describeType;
import flash.utils.getQualifiedClassName;
public class PropertiesHelper {
public function PropertiesHelper() {
}
private static var typePropertiesCache:Object = {};
public static function getPropertyNames(instance:Object):Array {
var className:String = getQualifiedClassName(instance);
if(typePropertiesCache[className]) {
return typePropertiesCache[className];
}
var typeDef:XML = describeType(instance);
trace(typeDef);
var props:Array = [];
for each(var prop:XML in typeDef.accessor.(#access == "readwrite" || #access == "readonly")) {
props.push(prop.#name);
}
return typePropertiesCache[className] = props;
}
public static function getNameValuePairs(instance:Object):URLVariables {
var props:Array = getPropertyNames(instance);
var vars:URLVariables = new URLVariables();
for each(var prop:String in props) {
vars[prop] = instance[prop];
}
return vars;
}
}
}
Use:
var blog:Blog = new Blog(1,"title&","text","cat","created");
var urlVars:URLVariables = PropertiesHelper.getNameValuePairs(blog);
trace(urlVars);
I'm using a URLVariables object since it seems that's what you want (though not actually what you blogURLVars method does), but you could change that in the getNameValuePairs method to suit your needs if necessary. An advantage of using a URLVariables object is that it handles the url-encoding for you automatically, so reserved characters such as &, =, etc, should not be a problem.