I have a problem with ActionScript (AS3) / JSON. There is probably a really simple answer to this, so I apologize if this seems like a really noob question.
What I am trying to do is take multiple text strings, place them into an object and then have that object sent as a JSON string to a server.
Every thing else in my code works fine, accept whenever I input a piece of text into my text input box and send the object, the array produces null entries like so:
{"email":null,"last_Name":null,"first_Name":null,"date_of_birth":null,"telephone":null}
However if I replace customer.first_name = inPutfname with: customer.first_name = " John";
Then the array traces back as the following which is what I want:
{"email":null,"last_Name":null,"first_Name":John,"date_of_birth":null,"telephone":null}
So how do I take the multiple input text strings and place them into the object so that the array reads back as it does in the above example, or ideally like this example:
{"email":randomemail#email.com"last_Name":smith,"first_Name":john,"date_of_birth":27/07/1989,"telephone":012343456788}
Here is the code I have so far:
var inPutFirstname: String;
var inPutLastname: String;
var inPutEmail: String;
var inPutTelephone: String;
var inPutDob: String;
// changes customer data into an object
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
var customer:Object = new Object;
customer.first_Name =inPutFirstname;
customer.last_Name = inPutLastname; PROBLEM AREA?
customer.email = inPutEmail;
customer.date_of_birth = inPutDob;
customer.telephone = inPutTelephone;
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\
//changes customer object into json string
var myJson: String = JSON.stringify(customer);
var myVariableUrl: URLVariables = new URLVariables();
myVariableUrl.data = JSON.stringify(myVariableUrl);
var myRequestUrl: URLRequest = new URLRequest();
var authHeaderUrl: URLRequestHeader = new URLRequestHeader("xxxxxx", "xxxxxxx");
myRequestUrl.method = URLRequestMethod.POST;
myRequestUrl.data = myJson;
myRequestUrl.url = "website url"
var uload: URLLoader = new URLLoader();
uload.load(myRequestUrl);
uload.load(myRequestUrl);
mySendbutton.addEventListener(MouseEvent.MOUSE_DOWN, thefunction1);
// captures text from the input and places them into the customer object
function captureText1(): void {
inPutFirstname = myFirstName.text;
inPutLastname = myLastName.text;
inPutEmail = myEmail.text;
inPutDob = myDob1.text + myDob2.text + myDob3.text;
inPutTelephone = myTele.text;
}
function thefunction1(event: MouseEvent): void {
captureText1();
trace(inPutfname);
trace(myJson);
}
Any Help would be Amazing.
Thanks guys
Your problem is that the code for creating the JSON object doesn't seem to be contained in a function, which means it will be executed immediately (considering this is probably code attached to a frame).
What you need to do is to is to wrap the code relating to creating the JSON object into a function, something like this:
(Please note that there are a lot of ways this code can be structured better, however this should illustrate some core concepts.)
var inPutFirstname: String;
var inPutLastname: String;
var inPutEmail: String;
var inPutTelephone: String;
var inPutDob: String;
function generateJSON():String {
var customer:Object = new Object();
customer.first_Name = inPutFirstname;
customer.last_Name = inPutLastname;
customer.email = inPutEmail;
customer.date_of_birth = inPutDob;
customer.telephone = inPutTelephone;
return JSON.stringify(customer);
}
function sendJSON(data)
var myVariableUrl: URLVariables = new URLVariables();
myVariableUrl.data = JSON.stringify(myVariableUrl);
var myRequestUrl: URLRequest = new URLRequest();
var authHeaderUrl: URLRequestHeader = new URLRequestHeader("xxxxxx", "xxxxxxx");
myRequestUrl.method = URLRequestMethod.POST;
myRequestUrl.data = data;
myRequestUrl.url = "website url"
var uload: URLLoader = new URLLoader();
uload.load(myRequestUrl);
}
mySendbutton.addEventListener(MouseEvent.MOUSE_DOWN, thefunction1);
// captures text from the input and places them into the customer object
function captureText1(): void {
inPutFirstname = myFirstName.text;
inPutLastname = myLastName.text;
inPutEmail = myEmail.text;
inPutDob = myDob1.text + myDob2.text + myDob3.text;
inPutTelephone = myTele.text;
}
function thefunction1(event: MouseEvent): void {
// First populate the string variables with user input
captureText1();
// Then generate the JSON string
var jsonData:String = generateJSON();
// Lastly, send the JSON string
sendJSON(jsonData);
trace(inPutfname);
trace(jsonData);
}
1st of all, can you add in function captureText1() traces for:
trace(myFirstName.text);
trace(myLastName.text);
trace(myEmail.text);
etc...
just to be sure that you have proper value in there.
And if you are, instead of using extra variables for that you can do (right after traces):
var customer:Object = new Object;
customer.first_Name = myFirstName.text;
customer.last_Name = myLastName.text;
customer.email = myEmail.text;
customer.date_of_birth = "" + myDob1.text + myDob2.text + myDob3.text;
customer.telephone = myTele.text;
var myJson: String = JSON.stringify(customer);
trace(myJson);
Related
I'm trying to load an array that contain some display objects, the program lets me to populate the array with circles and save them to a shared object, then, I can trace the content of my array using the load button. The problem is that i can't load the array after that I restart my program. It traces me this message:"objects loaded: ,,,"
This is the code:
var SO:SharedObject=SharedObject.getLocal("myFile", "/");
var arr:Array=new Array();
var counter:Number=-1;
addBtn.addEventListener(MouseEvent.CLICK, addObjects);
saveBtn.addEventListener(MouseEvent.CLICK, saveObjects);
loadBtn.addEventListener(MouseEvent.CLICK, loadObjects);
function addObjects(event:Event) {
counter++;
var circle:circleClip=new circleClip();
arr.push(circle);
trace("current object: "+arr[counter]);
}
function saveObjects(event:Event) {
SO.data.arrSaved=arr;
SO.flush();
trace("objects saved: "+SO.data.arrSaved);
}
function loadObjects(event:Event) {
var arrLoaded:Array=new Array();
arrLoaded=SO.data.arrSaved;
trace("objects loaded: "+arrLoaded);
}
You are to understand MVC pattern approach: https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
You need to separate data from the code that visualizes things out of these data, and store data only. Something like:
// Lets say this Array contains a list of your circle objects.
var Curcus:Array;
// Storage.
var SO:SharedObject = SharedObject.getLocal("myFile", "/");
function saveCircus():void
{
var aList:Array = new Array;
aList.length = Circus.length;
for (var i:int = 0; i < Curcus.length; i++)
{
// Get an object.
var aCircle:Sprite = Curcus[i];
// Record its properties you want to store.
var anEntry:Object =
{
"x":aCircle.x,
"y":aCircle.y,
"scaleX":aCircle.scaleX,
"scaleY":aCircle.scaleY
};
// Store the entry.
aList[i] = anEntry;
}
// Store and save data.
SO.data.arrSaved = aList;
SO.flush();
}
function loadCircus():void
{
// Retrieve saved data.
var aList:Array = SO.data.arrSaved;
// Make it empty data if there are none.
if (!aList) aList = new Array;
Circus = new Array;
Curcus.length = aList.length;
for (var i:int = 0; i < aList.length; i++)
{
// Get one entry.
var anEntry:Object = aList[i];
// Create a new item. BTW, naming classes with the
// lowercase first letter is the 8th cardinal sin.
var aCircle = new CircleClip;
// Restore saved properties.
aCircle.x = anEntry['x'];
aCircle.y = anEntry['y'];
aCircle.scaleX = anEntry['scaleX'];
aCircle.scaleY = anEntry['scaleY'];
// Add to display list.
addChild(aCircle);
// Keep it for the future reference/saving.
Curcus[i] = aCircle;
}
}
i have two arrays that are both connected to a scope (http get etc.):
$scope.allShops
that hold all the shop details and
$scope.allCds
that hold all the cd's
both work fine and the Ng-Repeat gives me all the output (individually) i need, i however would like to build a search that allows me to search on the cd name and on the shop name from the same search field (using a label to mention if its a shop or a cd to avoid confusion). So i came up with this:
$scope.allShops = [];
$scope.allCds = [];
var jointData1 = '';
var jointData2 = '';
var SearchAll = '';
var jointData1 = $scope.allShops;
console.info(jointData1);
var jointData2 = $scope.allCds;
console.info(jointData2);
var searchAll = jointData1.concat(jointData2);
console.info(searchAll)
But all the logs are empty, if i place the log inside the succes.array function it shows me the data object but placing the log with the scope outside give me nothing. How do i get the data outside the array function and able to concat the two scope?
Your console.info calls will be empty because the $http service hasn't got the data back yet.
You'd have to do this after the data is returned by using a promise (.then())
Just try this
function merge_options(obj1,obj2){
var obj3 = {};
for (var attrname1 in obj1) {
obj3[attrname1] = obj1[attrname1];
}
for (var attrname2 in obj2) { obj3[attrname2] = obj2[attrname2]; }
return obj3;
}
merge_options(obj1,obj2);
This problem has me stumped.
For some reason, the autoincrementing key generator in indexedDB resets after performing and update on an existing object with a put-transaction, leading to overwrites of data in the database.
For my app, I'm using a self written IndexedDB service for angularJS with all the basic CRUD functions implemented.
I may also add that I'm developing with Ionic Framework, even though I doubt that is to blame.
Considering the service is a work-in-progress, I've let the key path for an object store default to "id" with an autoincrementing strategy.
The indices for the given store, nevertheless, are up to the user to decide in a specific object.
As an example:
dbHelper.objectStores = [{'employees',
indices: [{indexName: 'name', isUnique: false},
{indexName: 'phone', isUnique: true}]}];
This would, unless already created in the db, create the object store 'employees' with indices 'name' and 'phone', where 'phone' would have to be a unique value while 'name' would not.
Here is the implementation of the openDB function.
Please note that dbHelper.objectStores is supposed to be empty as it's up to the user to assign these properties before opening the db(or else it is defaulted).
angular.module('dbProvider', [])
.factory('$db', ['$window', function($window) {
// DB Object
var dbHelper = {};
// Properties - Are given defaults unless assigned manually by user before openDB is invoked.
dbHelper.dbName = 'defaultDB';
dbHelper.dbVersion = 1;
dbHelper.objectStores = [];
dbHelper.openDB = function(onCompleteCallback, onErrorCallback) {
console.log('Atempting to open db with name ' + dbHelper.dbName + '.');
var request = $window.indexedDB.open(dbHelper.dbName, dbHelper.dbVersion);
// Invoked by indexedDB if version changes
request.onupgradeneeded = function(e) {
console.log('Version change. Current version: ' + dbHelper.dbVersion);
var db = e.target.result;
e.target.transaction.onerror = onErrorCallback;
if(dbHelper.objectStores.length === 0) {
dbHelper.objectStores.push({name:'defaultStore', indices: []});
}
for(var store in dbHelper.objectStores) {
if(db.objectStoreNames.contains(dbHelper.objectStores[store].name)) {
console.log(dbHelper.objectStores[store].name + ' deleted.');
db.deleteObjectStore(dbHelper.objectStores[store].name);
}
var newStore = db.createObjectStore(dbHelper.objectStores[store].name, {keyPath: "id", autoIncrement: true});
for(var index in dbHelper.objectStores[store].indices) {
newStore.createIndex(dbHelper.objectStores[store].indices[index].indexName,
dbHelper.objectStores[store].indices[index].indexName,
{unique : dbHelper.objectStores[store].indices[index].isUnique});
}
console.log(dbHelper.objectStores[store].name + ' created.');
}
};
request.onsuccess = function(e) {
console.log('DB ' + dbHelper.dbName + ' open.');
dbHelper.indexedDB.db = e.target.result;
onCompleteCallback();
};
request.onerror = onErrorCallback;
};
Here are some of the CRUD functions(the ones in question):
dbHelper.findItemWithIndex = function(keyValue, storename,
onCompleteCallback,onErrorCallback) {
var db = dbHelper.indexedDB.db;
var trans = db.transaction([storename], "readwrite");
var store = trans.objectStore(storename);
var index = store.index(keyValue.key);
index.get(keyValue.value).onsuccess = function(event) {
onCompleteCallback(event.target.result);
};
};
dbHelper.addItemToStore = function(item, storename,
onCompleteCallback, onErrorCallback) {
var db = dbHelper.indexedDB.db;
var trans = db.transaction([storename], "readwrite");
var store = trans.objectStore(storename);
var request = store.add(item);
trans.oncomplete = onCompleteCallback;
request.onerror = onErrorCallback;
};
dbHelper.deleteItemFromStore = function(itemId, storename,
onCompleteCallback, onErrorCallback) {
var db = dbHelper.indexedDB.db;
var trans = db.transaction([storename], "readwrite");
var store = trans.objectStore(storename);
var request = store.delete(itemId);
trans.oncomplete = onCompleteCallback;
request.onerror = onErrorCallback;
};
dbHelper.updateItem = function(item, storename, onCompleteCallback, onErrorCallback) {
var db = dbHelper.indexedDB.db;
var trans = db.transaction([storename], "readwrite");
var store = trans.objectStore(storename);
var request = store.put(item);
trans.oncomplete = onCompleteCallback;
request.onerror = onErrorCallback;
};
Finally, the code from the controller where the transactions are invoked.
The strategy here, is that the item is added to the db using the addItemToStore function the first time it is persisted, and then afterwards the updateItem function.
After adding the first time, the object is immediately fetched in order to keep working on it with the assigned id from the db.
$scope.updateTemplate = function() {
console.log('Saving..');
var onCompleteCallback = {};
if(!$scope.formTemplate.firstSave) {
onCompleteCallback = $scope.updateModel;
} else {
$scope.formTemplate.firstSave = false;
onCompleteCallback = $scope.setId;
}
$db.updateItem($scope.formTemplate, $scope.objectStore.name,
onCompleteCallback, $scope.dbError);
};
$scope.newItem = function() {
$db.addItemToStore($scope.formTemplate, $scope.objectStore.name,
$scope.setId, $scope.dbError);
};
$scope.setId = function() {
$db.findItemWithIndex(
{key: 'title',
value: $scope.formTemplate.title},
$scope.objectStore.name,
function(result) {
console.log(JSON.stringify(result));
$scope.formTemplate = result;
},
function(error) {
$scope.dbError(error);
});
}
It's here everything goes to hell.
I add an object, go back to another view and find it in the list with id=1.
I add another object, go back to the list view, and there it is with id=2.
And so forth and so forth..
Then, after updating either of the objects with the $scope.updateTemplate function, which also works like a charm, things get interesting:
The next object added gets id=1 and totally erases good old numero uno from earlier.
The next objects also get id's that cause them to replace the already existing objects.
What could cause this?
For testing I'm using Safari 8 in OS 10.10 and I'm deploying to an LGG2 with KitKat 4.4.2.
To be honest, I skimmed, but I saw this, "Safari 8" - the latest iOS and Safari have serious bugs with IndexedDB: http://www.raymondcamden.com/2014/9/25/IndexedDB-on-iOS-8--Broken-Bad
In iOS9, many of the IndexedDb bugs are fixed, but not all. We are currently testing on iOS9 Beta 2 and this particular bug that you found is not fixed.
We were able to work around this problem by not using autoincrement on our object stores. We just manually find the max key value and increment that.
Inserting an object looks something like this:
var store = db.transaction([entity], "readwrite").objectStore(entity);
store.openCursor(null, "prev").onsuccess = function (event) {
var maxKey = event.target.result.key || 0;
object.id = maxKey + 1;
store.add(object);
}
I'm learning Google Apps Scripts for use with Google Spreadsheets.
I have a list of URLs in one column and I want to write a script to get the title element from each URL and write it in the adjacent cell. I have accomplished this for one specific cell as per the following script:
function getTitles() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("url_list");
var range = sheet.getRange("G3");
var url = range.getValue();
var response = UrlFetchApp.fetch(url);
var doc = Xml.parse(response.getContentText(),true);
var title = doc.html.head.title.getText();
var output = sheet.getRange("H3").setValue(title);
Logger.log(title);
return title;
}
This gets the URL in G3, parses it, pulls the element and writes the output in H3.
Now that I have this basic building block I want to loop the entire G column and write the output to the adjacent cell but I'm stuck. Can anyone point me in the right direction?
May look something like this:
function getTitles() {
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("url_list");
var urls = sheet.getRange("G3:G").getValues();
var titleList = [], newValues = [],
response, doc, title;
for (var row = 0, var len = urls.length; row < len; row++) {
if (urls[row] != '') {
response = UrlFetchApp.fetch(urls[row]);
doc = Xml.parse(response.getContentText(),true);
title = doc.html.head.title.getText();
newValues.push([title]);
titleList.push(title);
Logger.log(title);
} else newValues.push([]);
}
Logger.log('newValues ' + newValues);
Logger.log('titleList ' + titleList);
// SET NEW COLUMN VALUES ALL AT ONCE!
sheet.getRange("H3").offset(0, 0, newValues.length).setValues(newValues);
return titleList;
}
I'm trying to get my SWF loader to work with an array so I can call my swf files via one code, using buttons.
This is the problem I am getting:
Scene 1, Layer 'actions', Frame 2, Line 68 1067: Implicit coercion of a value of type Array to an unrelated type String.
I am not too good with arrays, or strings, or coding tbh, i'm not too sure what the problem is, I understand it, my array and my string don't work together,basically, but I don't know how to fix it, if it can be fixed/work with the code I am using.
just some help and being pointed in the right direction would be a treat
var swfList:Array = ["imagegallery.swf", "videoplayer.swf"];
var SWFLoader = new Loader;
var SWFRequest = new URLRequest (swfList) ;
SWFLoader.load (SWFRequest) ;
function loadSWF(file:String, container:MovieClip=null):void
{
if(container == null) container = MovieClip(root);
if(SWFLoader != null)
{
if(SWFLoader.parent) SWFLoader.parent.removeChild(SWFLoader);
}
addChild (SWFLoader);
}
vidPlayer_btn.addEventListener (MouseEvent.CLICK, goVidPlayer);
function goVidPlayer (e:MouseEvent):void
{
loadSWF("videoplayer.swf");
}
imageGallery_btn.addEventListener(MouseEvent.CLICK, goImageGallery);
function goImageGallery(e:MouseEvent):void
{
loadSWF("imagegallery.swf");
}
To access items within an array use this format:
var SWFRequest = new URLRequest(swfList[i]);
Where i is the position in array (starting at zero).
For instance:
var SWFRequest = new URLRequest(swfList[0]);
gives the same result as:
var SWFRequest = new URLRequest("imagegallery.swf");
Did away with the array but still "have one code for both buttons instead of two separate codes".
// Looks unnecessary
// var swfList:Array = ["imagegallery.swf", "videoplayer.swf"];
// Transfer inside loadSWF()
// var SWFRequest = new URLRequest (swfList); // needs a url String parameter
// SWFLoader.load (SWFRequest);
var SWFLoader = new Loader(); // Don't forget the parenthesis
vidPlayer_btn.addEventListener (MouseEvent.CLICK, goVidPlayer);
imageGallery_btn.addEventListener(MouseEvent.CLICK, goImageGallery);
function goVidPlayer (e:MouseEvent):void
{
loadSWF("videoplayer.swf");
}
function goImageGallery(e:MouseEvent):void
{
loadSWF("imagegallery.swf");
}
function loadSWF(file:String, container:MovieClip=null):void
{
// What for?
// if(container == null) container = MovieClip(root);
if(SWFLoader != null)
if(SWFLoader.parent)
SWFLoader.parent.removeChild(SWFLoader);
var SWFRequest = new URLRequest (file) ;
SWFLoader.load (SWFRequest);
addChild (SWFLoader);
}