in the following code :
var benq:Base64Encoder = new Base64Encoder();
benq.encode("force",0,5);
var tmp:String = benq.toString();
'tmp' turns out to be an empty string, i.e. with length 0.
why?
how to encode a string using base64encoder?
Are you sure that your code isn't working.
I just copied and pasted it into a test app and it returned tmp as 'Zm9yY2U='
Are you doing anything else to the var tmp? if debugging make sure that it has processed the var tmp:String.... line when your checking the output
<?xml version="1.0" encoding="utf-8"?><mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
layout="vertical"
verticalAlign="middle"
backgroundColor="white"
creationComplete="but1.label = encodeit()">
<mx:Script>
<![CDATA[
import mx.utils.Base64Encoder;
private function encodeit(): String {
var benq:Base64Encoder = new Base64Encoder();
benq.encode("force",0,5);
var tmp:String = benq.toString();
return tmp;
}
]]>
</mx:Script>
<mx:Button
id="but1"
width="100"
height="100"
/></mx:Application>
Are you using Flex 3, as it seems to be a new feature? Also try encoding into a bytearray using encodeBytes and using encodeUTFBytes, perhaps these work better.
Online reference is available from Adobe, but I guess you know that.
Ok, it is working.
The code that I posted was different from what I was actually using.
I skipped over the fact that calling toString() for Base64Encoder
clears its internal buffer. So, calling it the next time would return
an empty string.
Sorry for the trouble.
Related
There is known issue in Internet Explorer (6,7) when Flex (HTTPService) is loading XML through SSL. Flash Player is throwing Error #2032: Stream Error in that case.
As advised by Microsoft and others, "Cache-Control: no-store" should be set on the server side to resolve the issue.
Unfortunately, I do not have access to application's backend, and thus I should solve it through Flex.
My goal is to load xml file with configurations at runtime.
Custom headers for GET requests are not allowed in Flex (let me know, if I am wrong). Thus I decided to accomplish my goal with POST request, and surprisingly it worked very well.
Here is the code I came with:
var httpService:HTTPService = new HTTPService();
httpService.url = 'config.xml';
httpService.method = 'POST';
httpService.requestTimeout = 10;
httpService.contentType = "application/xml";
httpService.headers["Cache-Control"] = "no-store";
httpService.resultFormat = "e4x";
var localResponder:Responder = new Responder(
function(event:ResultEvent):void {
//event.result returns the required xml configuration
},
function(event:FaultEvent):void {
});
var token:AsyncToken = httpService.send({});
token.addResponder(localResponder);
My question is: Could there be any side effects, when POST request is sent instead of GET request?
UPDATE:
To prove that GET-requests are stripped of headers, I've taken the code provided by #Reboog711 and created a little application. Here is the code:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx">
<fx:Script>
<![CDATA[
import mx.rpc.http.HTTPService;
protected function sendHTTPRequest(event:MouseEvent):void
{
var httpService:HTTPService = new HTTPService();
httpService.url = 'xml.xml';
var headerData : Object = new Object();
headerData['Cache-Control'] = 'no-store';
httpService.headers = headerData;
httpService.send();
}
]]>
</fx:Script>
<s:Button label="SEND HTTP REQUEST"
horizontalCenter="0" verticalCenter="0" click="sendHTTPRequest(event)"/>
</s:Application>
And here is what I see in Charles application, when I send that HTTP-request.
You can test it yourself right here. Moreover, while I was trying to solve my problem, I've seen many evidences that GET-requests couldn't be sent with custom headers. You may take a look here.
Thanks!
You should be able to add headers to an HTTPService request without any problems. I have done it before, when integrating a Flex app with the YouTube APIs. Conceptually, it should be like this:
var httpService:HTTPService = new HTTPService();
var headerData : Object = new Object();
headerData['Cache-Control'] = 'no-store';
http.headers = headerData;
If you perform a Google Search other links come up. So long as your service supports both GET and POST requests; I do not know why you would experience any issues.
I'm new to Actionscript programming. I'm trying to figure out what is the best way to return multiple variables, each having a different data type, from a function. For example, if a function needs to return variable aa ( a string) and variable bb (a number).
The function I'm using just crunches a lot of math, and doesn't relate to an object in a GUI. One method I got from a Google search used an Object, but as (I think) this requires me to create a class, I wondered if there was a simpler way. Since an array can hold elements of different data types, perhaps this is a simpler approach (?).
Here's an example mxml and AS3 file taken from "Flash Builder 4 and Flex 4 Bible" by David Gassner.
file: Calculator.mxml
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:components="components.*">
<fx:Script source="calculator.as"/>
<s:Panel title="Calculator" horizontalCenter="0" top="20">
<s:layout>
<s:VerticalLayout horizontalAlign="center"/>
</s:layout>
<mx:Form>
<components:ButtonTile id="input"
select="selectHandler(event)"
calculate="calculateHandler(event)"/>
<mx:FormItem label="Entry:">
<s:TextInput text="{currentInput}" editable="false" width="80"/>
</mx:FormItem>
<mx:FormItem label="Total:">
<s:TextInput text="{currentResult}" editable="false" width="80"/>
</mx:FormItem>
</mx:Form>
file: calculator.as
//ActionScript code for Calculator.mxml
[Bindable]
private var currentResult:Number=0;
[Bindable]
private var currentInput:String="";
private function calculateHandler(event:Event):void
{
currentResult += Number(currentInput);
currentInput="";
}
private function selectHandler(event:TextEvent):void
{
currentInput += event.text;
}
Could someone illustrate how to modify one of the functions in calculator.as, just as an example how to return two values, where one is a number and the other a string? Is there an obvious best-way to do this, or, what would be the pros/cons of different approaches? Thanks in advance!
You could just simply return an Object which is dynamic and thus lets you define values on the fly, like this:
return {something: "string", another: 18};
Or:
var obj:Object = {};
obj.something = "string";
obj.another = 18;
return obj;
But in my opinion this is really poor practice (especially if your function is to return the same sets of information with new values).
I'd take this route:
You can create your own class that holds various properties. From there you can return an instance of this object with the properties defined as you wish.
Example:
This would be in an external file called CollisionData.as
package
{
public class CollisionData
{
public var x:Number = 0; // X coordinate of the collision
public var y:Number = 0; // Y coordinate of the collision
public var angle:Number = 0; // Collision angle
}
}
And your function could be:
function calculate():CollisionData
{
var col:CollisionData = new CollisionData();
// determine collision details
col.x = 115;
col.y = 62;
col.angle = 0.345;
return col;
}
Then you can create your own collision data based off the result:
var myCollision:CollisionData = calculate();
And fetch the details:
trace(
myCollision.x,
myCollision.y,
myCollision.angle
);
No need to create class, this should work for you:
public function calculate():Object
{
return {valueA: "string", valueB: 1};
}
Ive read a ton of online tutorials about this and cant seem to get a definite answer...
View1.mxml
navigator.pushView(views.view2, {response:"BLAH"});
View2.mxml
<fx:Script>
<![CDATA[
var result:String = // FIRST VIEW RESPONSE WHICH = BLAH
]]>
</fx:Script>
How is this done? Surely it should be simple? All the tutorials online seem very indepth!
Thanks
Phil
The property you are looking for is called data. It will get set AFTER construction. So, once data is set, you want to access data.response.
Got it
navigator.pushView(views.view2, "BLAH");
var result:String = String(data);
Duhhh
I understand that one can use local-specific ResourceBundles in combination with DateFormatters to format dates according to locale. However this is a manual process - is there an automatic way to do this or to set a default for the application?
In Java for example, all your dates will automatically appear in dd/mm/yy or mm/dd/yy format simply by setting the locale. In Flex, a default date output will always be in US format unless manually formatted otherwise. I'm looking for a way to get closer to the Java functionality.
I did this recently using flah.globalization classes:
see its very informative about getting locale etc..
http://www.adobe.com/devnet/flashplayer/articles/flash_globalization_package.html
here's my code:
remember to call init(); on creation complete !
<fx:Script>
<![CDATA[
import flash.globalization.DateTimeFormatter;
import flash.globalization.DateTimeStyle;
import flash.globalization.StringTools;
import mx.collections.ArrayCollection;
import spark.events.IndexChangeEvent;
[Bindable]
private var listColl:ArrayCollection;
private var localeList:Array = new Array("en-US", "fr-FR", "es-ES","ja-JP", "hi-IN","ru-RU");
private var country:String;
private function init():void{
// set the dp for drop down;
listColl = new ArrayCollection(localeList);
country = localeList[0];
}
private function doDateLabel(item:Date):String {
trace("input = " + item);
if(item != null) {
var locale:String = country;
if(locale != null){
var dtf:DateTimeFormatter = new DateTimeFormatter(locale);
dtf.setDateTimeStyles(DateTimeStyle.SHORT, DateTimeStyle.NONE);
/*
DateTimeSyle.MEDIUM
DateTimeSyle.LONG
*/
var shortDate:String = dtf.format(item);
trace(shortDate + " (" + dtf.getDateTimePattern() + ")");
}
}
return shortDate;
}
protected function dropDownList_changeHandler(evt:IndexChangeEvent):void {
country = countryList.selectedItem;
}
]]>
</fx:Script>
<s:HGroup width="100%" height="100%" gap="20" top="50" left="50">
Hope that's what you were after
<mx:DateField id="begin" width="200"
showToday="true"
labelFunction="doDateLabel"
parseFunction="null"/>
<s:DropDownList id="countryList"
requireSelection="true" prompt="Please select an Country"
horizontalCenter="0" top="20" dataProvider="{listColl}"
change="dropDownList_changeHandler(event);">
</s:DropDownList>
</s:HGroup>
Look at toLocaleString and toLocaleTimeString
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Date.html#toLocaleString()
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/Date.html#toLocaleTimeString()
It is a feature of Flash Player 10.1 placed in flash.globalization package
The flash.globalization package in Flash Player: Cultural diversity without complexity
I'm still a newbie to Adobe Air/Flex, and still fairly new with SQL.
I've downloaded this (http://coenraets.org/blog/2008/11/using-the-sqlite-database-access-api-in-air…-part-1/) code and have been looking over it and I'm trying to implement the same idea.
I think it's just something stupid. I'm using Flex Builder. I made a new desktop application project, didn't import anything.
I added a DataGrid object and bound it to an ArrayCollection:
I'm trying to make it so when the program initializes it will load data from a database if it exists, otherwise it'll create a new one.
The problem is, when the application runs, the datagrid is empty. No column headers, no data, nothing. I've tried changing a whole bunch of stuff, I've used the debugger to make sure all the functions are being called like they're supposed to. I don't know what I'm doing wrong. I've compared my code to the before mentioned code, I've looked for tutorials on Google. Anyone know what I'm doing wrong?
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="672" height="446"
applicationComplete="onFormLoaded()"
title="iRecipes">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
private var sqlConnection:SQLConnection;
[Bindable] private var recipeList:ArrayCollection;
private function onFormLoaded():void
{
sqlConnection = new SQLConnection();
openDataBase();
}
private function openDataBase():void
{
var file:File = File.userDirectory.resolvePath("recipes.db");
sqlConnection.open(file, SQLMode.CREATE);
if(!file.exists)
{
createDatabase();
}
populateRecipeList()
}
private function createDatabase():void
{
var statement:SQLStatement = new SQLStatement();
statement.sqlConnection = sqlConnection;
statement.text = "CREATE TABLE Recipes (recipeId INTEGER PRIMARY KEY AUTOINCREMENT, recipeName TEXT, authorName TEXT)";
statement.execute();
statement.text = "INSERT INTO Recipes (recipeName, authorName) VALUES (:recipeName, :authorName)";
statement.parameters[":recipeName"] = "Soup";
statement.parameters[":authorName"] = "Joel Johnson";
statement.execute();
statement.parameters[":recipeName"] = "Garbage";
statement.parameters[":authorName"] = "Bob Vila";
statement.execute();
}
private function populateRecipeList():void
{
var statement:SQLStatement = new SQLStatement();
statement.sqlConnection = sqlConnection;
statement.text = "SELECT * FROM Recipes";
statement.execute();
recipeList = new ArrayCollection(statement.getResult().data);
}
]]>
</mx:Script>
<mx:DataGrid dataProvider="{recipeList}">
</mx:DataGrid>
</mx:WindowedApplication>
I just tried this out using your code. I made a change and removed the condition as I was getting errors about the table not existing.
//if(!file.exists)
//{
createDatabase();
//}
This got the datagrid showing the correct info. I think that there is something wrong with the way you are initialising the database file. I'm having a look into it at the moment.
Try using
sqlConnection.open(file, SQLMode.CREATE);
instead, for opening the database.
Thanks Feet. With your suggestion, I believe I have figured it out. I changed the if statement to this:
if(!file.exists)
{
sqlConnection.open(file, SQLMode.CREATE);
createDatabase();
}
else
{
sqlConnection.open(file, SQLMode.UPDATE);
}
And it works great. Thanks for your help.