i have an error(s), it's not working, which are the errors [closed] - json

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
package {
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.net.*;
import com.adobe.serialization.json.*;
public class ScreenCategories extends Sprite {
public var myLoader:URLLoader;
public var filePath:String;
public var myReq:URLRequest;
public function ScreenCategories() {
// constructor code
reLoad();
}
// Constructor: Create an array of three categories
public function reLoad()
{
lastButtonEndedY = 35;
/*
In our real app, we would load in the categories from our database (via a JSON)
Hint: Saving the Objects into the array at the index that equals the ID is advised
*/
filePath = "getCategories.php"; //declare path and file name
myReq = new URLRequest(filePath); //create URLRequest to access the file
myLoader = new URLLoader(); //create URLLoader to load the file
//add event listener to run fileLoaded function when loading is complete
myLoader.removeEventListener(Event.COMPLETE, loadComplete);
myLoader.addEventListener(Event.COMPLETE, loadComplete);
//add event listener to listen for any error thrown during loading process
myLoader.removeEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
myLoader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
myLoader.load(myReq); //start loading a file with our URLLoader instance
}
//loading complere so print content of a text file to our Text Field
function loadComplete(e:Event):void
{
var jsonstring:String = myLoader.data;
var categories:Array = JSON.decode(jsonstring);
for (var count:int = 0; count < categories.length; count++) {
var aCategory:Object = category[count];
trace(aCategory.categoryname);
trace(aCategory.categoryid);
}
///////////////
// Consider that it would be more responsible to add these to an array and maintain
// which are being added/deleted, then we could create a print function!
///////////////
}
//if any error was thrown, event was also dispatched and now you can print
//the error description to the text field.
public function ioErrorHandler(e:IOErrorEvent):void
{
trace("There was a problem loading "+filePath+": "+e);
}
}
}
// for each "category" in our list (Array)...
for (var count in categories)
{
// Create a button for each of the categories that exist in our Array
var aCategory:BtnCategory = new BtnCategory(categories[count].category);
// Add the BtnCategory to the stage
aCategory.x = 0;
aCategory.y = lastButtonEndedY;
aCategory.name = categories[count].id; // give it a unique name!
addChild(aCategory);
lastButtonEndedY += (aCategory.getHeight() + 1);
}
addEventListener(MouseEvent.CLICK, mouseClicked);
This is supposed to work on Action script 3 for a mobile app where i need a category list that will take me to a product list and the a product.... but i'm working first on the category list where the values are read from JSON, i already have a getCategory.php document where my json was returned correctly..... but when i run the swf it says error....

To me it looks like filePath = "getCategories.php"; is your problem.
When you run locally or in your dev environment it will look for that php page in the same directory that the SWF is in which will probably work fine for you. But when you publish to a phone that is no longer the location of the php page.
As such you will probably get the IO error since the server does not exist.
[EDIT]
Well now that you finally posted the error I can see what your issue is.
type was not found or was not a compile-time constant: Event
Is stating that it can not find the Event class.
Looking at your code you are not importing it either.
The closest you come to it is the MouseEvent.
So instead of just importing the MouseEvent try this.
import flash.events.*;

Related

How to exclude Library item from compiling if it is not present AS3

I have a MovieClip in Library , which I am loading dynamically through addChild method.
The problem I am facing is :--
I have a Main Class which runs with several other classes and several FLA's.
Main Class calls a sub class function which in return calls the code in a frame of a FLA which loads this object from Library.
This object is not present in all FLA's, thats where I am getting stuck, getting Compile time error.
Tried checking through this but failed :(
var classExist:Boolean = isClassExists("CTRL_ALARM");
function isClassExists(className:String, domain:ApplicationDomain = null):Boolean
{
var res:Boolean;
if(domain)
{
res = domain.hasDefinition(className);
}
else
{
// res = getDefinitionByName(className);
//or the same
res = ApplicationDomain.currentDomain.hasDefinition(className);
}
trace(res);
return res;
}
Is there any way I can duplicate objects on Stage in as3, or how can I restrict an object from being compiled if it is not present in Library?
Try the following. If all of your SWFs are in the same sandbox, it might just work:
import flash.utils.getDefinitionByName;
var AlarmClass:Class = getDefinitionByName("CTRL_ALARM");
var anAlarm:DisplayObject = new AlarmClass;
Then, to make it work even with sandbox restrictions, you may seek for the definition you want through the loaded SWFs:
// This should contain Loader objects with your loaded SWFs.
var aList:Array;
for each (aLoader:Loader in aList)
{
// Get reference to loaded app domain.
var aDomain:ApplicationDomain = aLoader.contentLoaderInfo.applicationDomain;
// Check if such a class is in that SWF.
if (aDomain.hasDefinition("CTRL_ALARM"))
{
var AlarmClass:Class = aDomain.getDefinition("CTRL_ALARM");
var anAlarm:DisplayObject = new AlarmClass;
break;
}
}

AS3 Air Desktop - Dispatch Custom Event from SWF in ApplicationStorageDirectory

I have a series of Air Desktop games that I created. Before the game can be played, the user must first log in. In order to streamline things, I created the login system in a separate project and saved it as a swf file called, "dashboard.swf". When the game is opened, it loads dashboard.swf and displays the login screen. In addition to the login functionality, dashboard.swf also handles a bunch of other stuff like common settings amongst the games.
I didn't want to recompile each game every time I made a change to the dashboard.swf. So, I have it download from a server. I was originally downloading, saving, and loading dashboard.swf in the ApplicationDirectory and it worked fine on Macs. After testing on Window 10 and doing some research, I found that ApplicationDirectory for non-OSX machines is read-only.
So, I changed the location of the dashboard.swf to the ApplicationStorageDirectory. When I run it on my Mac, the swf loads just fine, but the first custom event that gets dispatched throws and error:
TypeError: Error #1034: Type Coercion failed: cannot convert com.thisapp.event::CustomEvent#12786a9fed31 to com.thisapp.event.CustomEvent
Both CustomEvent.as files are identical. It fires just fine when dashboard.swf is saved to and loaded from the ApplicationDirectory on the Mac. Once I move it to ApplicationStorageDirectory, I get this error. So I know it's not an issue with the actual custom dispatcher. Bubbling is true and so in Cancellable.
What would be causing the Type Coercion failure in this situation?
Here's my custom dispatcher:
public class CustomEvent extends Event {
public static const GOT_RESULT: String = "gotResult";
public var result: Object;
public function CustomEvent(type: String, result: Object = null, bubbles: Boolean = false, cancelable: Boolean = false) {
// constructor code
super(type, bubbles, cancelable);
this.result = result;
}
public override function clone(): Event {
return new CustomEvent(type, result, bubbles, cancelable);
}
}
From my dashboard.swf:
dispatchEvent(new CustomEvent(CustomEvent.GOT_RESULT, null,true,true));
In my Main class for the desktop app:
var dashboardURL:String = File.applicationStorageDirectory.url +"dashboard.swf";
var myContext:LoaderContext = new LoaderContext();
myContext.applicationDomain = ApplicationDomain.currentDomain;
var urlReq:URLRequest = new URLRequest(dashboardURL);
var ldr:Loader = new Loader();
ldr.load(urlReq, myContext);
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE,loadit);
function loadit(e:Event){
dashboard = e.target.content as MovieClip;
addChild(dashboard);
dashboard.addEventListener(CustomEvent.GOT_RESULT, runLogin);
}
ANSWER
See #BadFeelingAboutThis's answer below to understand why the 1034 error is happening. Here's how I fixed it:
First - Download the swf from the server (I'm using the GreenSock's LoaderMax):
private function dowloadDashboard(){
var url:String = "https://path/to/your/swf/on/the/server.swf";
var queue:LoaderMax = new LoaderMax({name:"mainQueue",onComplete:completeHandler});
//Note: the format is set to "binary"
queue.append( new DataLoader(url, {name:"mySwf",format:"binary", estimatedBytes:3000}) );
queue.load();
function completeHandler(event:LoaderEvent):void {
//Note: "mySwf" is the name I gave to the DataLoader above.
var b:ByteArray = LoaderMax.getContent("mySwf");
//loadDashboard() is the next function and I'm passing the ByteArray to it.
loadDashboard(b);
}
}
Next - Load the swf with the proper context using the ByteArray:
private function loadDashboard(b:ByteArray) {
var myContext:LoaderContext = new LoaderContext();
myContext.allowLoadBytesCodeExecution = true;
myContext.allowCodeImport = true;
myContext.applicationDomain = ApplicationDomain.currentDomain;
var ldr:Loader = new Loader();
ldr.loadBytes(b,myContext);
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE,loadDone);
}
Last - Add your swf to the stage:
function loadit(e:Event){
dashboard = e.target.content as MovieClip;
addChild(dashboard);
}
I hope that helps somebody! Remember, in my situation, I have a Desktop Air app that is downloading and loading a swf file that lives on a server.
This error typically means that you have the same Class coming into your root application from different sources.
In your case CustomEvent class must exist in both the host SWF file as well as your loaded in SWF file.
Because your loaded SWF is not in the same application domain as the host SWF, flash/AIR will not see overlapping classes as the same class. So you loaded in SWF CustomEvent is now seen as com.thisapp.event::CustomEvent#12786a9fed31 which (though exactly the same) is seen as a totally different class than com.thisapp.event:CustomEvent. Since your code references the latter, anytime a CustomEvent from the host tries to get stuffed in an object reference typed :CustomEvent it will throw a coercion error because they aren't actually same class.
Usually, the remedy for this problem is to specify the context for the loaded SWF so it integrates the loaded Classes into it's own domain. This should overwrite the host CustomEvent with the loaded SWF's CustomEvent
var ldr:Loader = new Loader();
//The second parameter for load takes a LoaderContext
ldr.load(new URLRequest(File.applicationStorageDirectory.url +"dashboard.swf"), new LoaderContext(false, ApplicationDomain.currentDomain));
ldr.contentLoaderInfo.addEventListener(Event.COMPLETE,loadit);
function loadit(e:Event){
dashboard = e.target.content as MovieClip;
addChild(dashboard);
dashboard.addEventListener(CustomEvent.GOT_RESULT, runLogin);
}
Read more about the loader context here and here

Why might browseForOpen fail to display File Dialog yet claim it is open if recalled?

I am trying to open a file dialog with file.browseForOpen. Most of the time it works but on the very rare occasion (such as in meetings) the file browser simply does not appear and does not block (as a modal should).
If I press the button calling the code at this point then I get an error which states "there can only be one".
There are no sub-windows and I can't find to file dialog, even after minimizing the main window, yet the error insists that it is open. I wrote some code which disabled the button when the code above is called and then enables it on any of the events but when this error occurs the button is then permanently disabled.
There are another 10,000 lines of code, some which keep running even while the file browser is open. None of them seem related to the file browser so I moved the following code into a new project, to test, and could not replicate the bug.
var filter:FileFilter = new FileFilter("Image/Video", "*.jpg;*.png;*.mp4;");
var imagesFilter:FileFilter = new FileFilter("jpg/png", "*.jpg;*.png");
var docFilter:FileFilter = new FileFilter("mp4", "*.mp4;");
var filters:Array = [filter, imagesFilter, docFilter];
var fileBrowser:File = File.userDirectory;
fileBrowser.addEventListener(FileListEvent.SELECT_MULTIPLE, onFileSelected);
fileBrowser.addEventListener(Event.CANCEL, clean);
fileBrowser.addEventListener(IOErrorEvent.IO_ERROR, clean);
fileBrowser.browseForOpen("Select Slides", filters);
Does anyone know anything which could save me from a 'needle in a haystack' exhaustive search? Has anyone else ever experienced this same problem? I couldn't find any solutions when searching "File dialog opens but isn't visible" or more than 30 variations of that search including "File dialog doesn't open".
Lastly, is there a way to force the file dialog to close if I detect that the user is interacting with the main window whilst it should be blocked? Just as a bandage fix should the problem not be solved (breaks modal flow, I know, but modal flow is already broken at that point).
UPDATE:
After removing a class and replacing it with a less efficient urlMonitor the problem seems to have gone away.
If anyone can work out what went wrong then I will mark your answer as complete.
The class I removed seemed completely unrelated but I will show the code:
package reuse.Network
{
import flash.desktop.NativeApplication;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.events.IOErrorEvent;
import flash.events.StatusEvent;
import flash.events.TimerEvent;
import flash.net.URLLoader;
import flash.net.URLLoaderDataFormat;
import flash.net.URLRequest;
import flash.utils.Timer;
import air.net.URLMonitor;
[Event(name="networkStatusChanged", type="reuse.Network.CheckInternetEvent")]
public class NetStatusMonitor extends EventDispatcher
{
private var url:String;
private var urlMonitor:URLMonitor;
public function NetStatusMonitor(url:String = 'http://www.adobe.com')
{
super();
this.url = url;
}
protected function onNetwork_ChangeHandler(event:Event):void
{
checkWebsite(url, dispatchStatus);
}
/**
* Checks a specific website for connectivity.
* #param uri URI of the website to check for a response from
* #param result Function which accepts a bool as a response.
* #param idleTimeout How many milliseconds to wait before timing out
*/
public function checkWebsite(uri:String, result:Function, idleTimeout:Number = NaN):void
{
var timeout:Timer;
var request:URLRequest = new URLRequest(uri);
if(!isNaN(idleTimeout))
{
request.idleTimeout = idleTimeout;
timeout = new Timer(request.idleTimeout + 1000, 1);
timeout.addEventListener(TimerEvent.TIMER_COMPLETE, failed);
timeout.start();
}
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.addEventListener(Event.COMPLETE, complete);
loader.addEventListener(IOErrorEvent.IO_ERROR, failed);
loader.load(request);
function complete():void
{
result(true);
cleanup();
}
function failed(e:*):void
{
result(false);
cleanup();
}
function cleanup():void
{
if(timeout)
{
timeout.stop();
timeout.removeEventListener(TimerEvent.TIMER_COMPLETE, failed);
timeout = null;
}
loader.close();
loader.removeEventListener(Event.COMPLETE, complete);
loader.removeEventListener(IOErrorEvent.IO_ERROR, failed);
loader = null;
}
}
public function start():void
{
checkWebsite(url, dispatchStatus, 5000);
if(!NativeApplication.nativeApplication.hasEventListener(Event.NETWORK_CHANGE))
NativeApplication.nativeApplication.addEventListener(Event.NETWORK_CHANGE, onNetwork_ChangeHandler);
if(urlMonitor == null)
{
var request:URLRequest = new URLRequest(url);
urlMonitor = new URLMonitor(request);
urlMonitor.pollInterval = 30;
}
if(!urlMonitor.hasEventListener(StatusEvent.STATUS))
urlMonitor.addEventListener(StatusEvent.STATUS, onNetStatus_ChangeHandler);
if(!urlMonitor.running)
urlMonitor.start();
}
public function stop():void
{
if(urlMonitor)
{
if(urlMonitor.running)
urlMonitor.stop();
if(urlMonitor.hasEventListener(StatusEvent.STATUS))
urlMonitor.removeEventListener(StatusEvent.STATUS, onNetStatus_ChangeHandler);
urlMonitor = null;
}
}
private function onNetStatus_ChangeHandler(event:StatusEvent):void
{
dispatchStatus(urlMonitor.available);
}
private function dispatchStatus(status:Boolean):void
{
dispatchEvent(new CheckInternetEvent(CheckInternetEvent.NETWORK_STATUS_CHANGED, status));
}
}
}
Anyone familiar with Raja Jaganathan might recognize this class from Adobe Air - Check for internet connection
I posted this as a bug to Adobe and the following note was added to it:
Alex Rekish
11:06:11 PM GMT+00:00 Apr 12, 2016
I have seen this problem and found workaround. You need remove
listeners, force cancel and null pervious file object that you you for
browseForOpen method.
previousBrowseFile.removeEventListener(Event.SELECT,
fileSelected); previousBrowseFile.removeEventListener(Event.CANCEL,
fileCancelled); previousBrowseFile.cancel(); previousBrowseFile= null;

Returning a string in Action Script 3.0

I'm really not familiar with Action Script 3 at all but I am with other languages.
I'm hoping someone could help me.
I'm attempting to make a modification to JWplayer so that an rtmp stream is retrieved via a PHP script rather than it being supplied in the HTML.
The code I currently have is below:
function useData(event:Event):void {
var data:String = event.target.data.toString();
}
/** Load content. **/
override public function load(itm:PlaylistItem):void {
_item = itm;
_position = 0;
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, useData);
loader.load(new URLRequest("http://192.168.0.12/phpauth/play1.php"));
// Set Video or StageVideo
if(!_video) {
_video = new Video(320, 240);
_video.smoothing = true;
_video.addEventListener('renderState', renderHandler);
// Use stageVideo when available
if (_stageEnabled && RootReference.stage['stageVideos'].length > 0) {
_stage = RootReference.stage['stageVideos'][0];
_stage.viewPort = new Rectangle(0,0,320,240);
_stage.addEventListener('renderState', renderHandler);
}
attachNetStream(_stream);
}
// Load either file, streamer or manifest
if (_item.file.substr(0,4) == 'rtmp') {
// Split application and stream
var definst:Number = _item.file.indexOf('_definst_');
In the load function the file name to play is held in _item.file. I'm trying to make a call to a php script which then overwrites the value in _item.file. I've confirmed that the php is being called but I don't know how to get the data from the data string in the useData function into the _item.file string.
Any help would be really appreciated - I suspect this is a simple one but my lack of AS3 knowledge is making it really difficult.
Thanks,
Your problem basically about how to access a local variable in an event handler. A quick and dirty way can be to have an anonymous function used as a handler like:
loader.addEventListener(Event.COMPLETE, function(event:Event):void {
var data:String = event.target.data.toString();
_item.file = data;
});
This approach would work, because this anonymous function has access to the local variables inside load function as is. But, you need to be cautious that the anonymous function uses the variable exactly as the calling function is using. So, let's say there is a loop in load function and _item changes in every iteration of the loop. For that scenario, when load handler gets called, its _item would also have changed to the object which was last assigned to _item.
A far cleaner and OO approach can be to have a handler class like:
package {
public class LoadHandler {
private var _item:PlaylistItem;
public function LoadHandler(item:PlaylistItem) {
_item = item;
}
public function loadHandler(event:Event):void {
var data:String = event.target.data.toString();
_item.file = data;
}
}
and then have loader.addEventListener(Event.COMPLETE, (new LoadHandler(_item)).loadHandler). Hope that helps. BTW, LoadHandler could be made more generic to take and array of objects to be used and a callback function. loadHandler function, then could just call callback function with that array of objects.
If you are returning a simple string from PHP you should be able to use
event.target.data;
e.g. from PHP... echo "hello";
var data:String = event.target.data
You could try tracing the response to ensure you are getting something back from PHP.
You can either test this from within the IDE or install the Debug version of the Flash Player browser plugin.
trace("Response from PHP: "+event.target.data);
_item.file = event.target.data;
trace("_item.file: "+_item.file);

AS3 Retrieving a file from FZip

I am currently coding a game and I am storing all external files in a zip file to save space.
I am trying to use Fzip to load an image out of the Zip file and display it on stage but I am having no luck.
FZip Site - http://codeazur.com.br/lab/fzip/
Example 1 Site - http://www.tuicool.com/articles/7VfQr2
I have got the zip file to load and return me the number of files inside it but I cannot figure out how to retrieve an image called "test.png".
import deng.fzip.FZip;
import deng.fzip.FZipFile;
import deng.fzip.FZipLibrary;
import flash.display.*;
var zip:FZip = new FZip();
var loaderzippy:Loader = new Loader();
function unzipObb():void {
zip.load(new URLRequest("file://"+File.applicationStorageDirectory.nativePath+"/cake2.zip"​));
zip.addEventListener(Event.OPEN, onOpen);
zip.addEventListener(Event.COMPLETE, dosomething); }
function dosomething(evt:Event):void {
trace("dosomething");
var img_file:FZipFile = zip.getFileByName("test.png");
var loaderzip:Loader = new Loader();
loaderzip.loadBytes(img_file.content);
var image:Bitmap = Bitmap(loaderzip.content);
addChild(image); }
I just get returned #2007: Parameter child must be non-null.
Any help would be great. Thanks.
When you load the PNG bytes using loaderzip.loadBytes(), you need an event listener to check when it's done loading. The documentation itself states:
The loadBytes() method is asynchronous. You must wait for the "init" event before accessing the properties of a loaded object.
Because you're trying to access the code directly after you called loadBytes(), at which point it hasn't actually loaded anything, you're getting a null bitmap.
Although you can access the data once the "init" event has been dispatched, it's best to wait for the "complete" event, since you want your image to be done loading (rather than halfway done).
I've tweaked your code to something that should work:
function dosomething(evt:Event):void {
trace("dosomething");
var img_file:FZipFile = zip.getFileByName("test.png");
var loaderzip:Loader = new Loader();
loaderzip.contentLoaderInfo.addEventListener(Event.COMPLETE, getImage);
loaderzip.loadBytes(img_file.content);
}
function getImage(e:Event):void {
var loaderInfo:LoaderInfo = e.currentTarget as LoaderInfo;
var image:Bitmap = Bitmap(loaderInfo.content);
addChild(image);
}
(I haven't tested this myself but it's just to give you the general idea anyway.)
Note that you should add the event listener to loaderzip.contentLoaderInfo, not just loaderzip. That's what actually dispatches the event and it also contains the loaded content.