AS3:
ExternalInterface.addCallback('getParams', getParams);
function getParams()
{
var params:Array = new Array();
for(i = 0; i < images.length; i++)
{
params.push(picWin.getChildAt(i));
}
return params;
}
JS:
$('#button').click(function(){
var res = document.getElementById("swfobject").getParams();
alert(res);
})
So after i get an error of some NPO object error, can't figure it out what it means, but if I pass an array itself its ok, if I pass an object itself it will be also ok, but when i pass an array of objects it gives me an error NPO, how to fix this?
To pass from AS to JS you want to use
ExternalInterface.call("myJsFunction", myArray);
for this example, you need 2 JS functions: the first handles the click and sends a request to your swf. The second is called by the swf with your return value:
AS3:
ExternalInterface.addCallback('getParams', getParams); // listens for JS to getParams
function getParams()
{
var params:Array = new Array();
for(i = 0; i < images.length; i++)
{
params.push(picWin.getChildAt(i));
}
ExternalInterface.call("handleParams", params); // calls a js function and passes params
}
JS:
$('#button').click(handleClick)
function handleClick(event){
document.getElementById("swfobject").getParams(); //sends request to swf
}
function handleParams(params){ // handles response from swf
alert("You got an array with " + params.length + " elements back from flash.");
}
Related
I am using the $.Deferred method to try and get a function to load some Json, work on the results, then pass the value back to another function that will use the result (in this case I expect an integer). For some reason I can get this integer displayed using either alert or console.log functions, but when it comes to using it as the return value of the actual function the code falls over and returns undefined.
For reference here's my code:
function NewValue(){
var dataPromise = GetDataFromJson();
dataPromise.done(function(data){
//note both console.log(data) and alert(data) deliver the correct result here
return data;
});
}
function GetDataFromJson() {
var jsonData;
var deferred = $.Deferred();
d3.json("http://localhost:8000/pipeline.json", function(dataFromServer){
jsonData = dataFromServer;
headers = ["Won"];
myTotal = 0;
chunks = (headers.map(function(priceRange) {
return jsonData.map(function(d) {
return {y: +d[priceRange]};
});
}));
var myTarget = 10000000;
chunks.forEach( function (arrayItem)
{
var l = 12;
for(var i = 0; i < l; i++) {
myTotal += arrayItem[i].y;
};
});
myTotal = myTotal/myTarget*100;
deferred.resolve(myTotal);
});
return deferred.promise();
}
Is it ever possible to return the value from GetDataFromJson() and use it, or will I only ever be able to log it to the console?
EDIT after reading through the answer the only way to do this is to call the gauge update function within my GetDataFromJson call - all these promises were seemingly pointless distractions from just passing the right info across:
function GetDataFromJson(f) {
var jsonData;
var deferred = $.Deferred();
d3.json("http://localhost:8000/pipeline.json", function(dataFromServer){
jsonData = dataFromServer;
if( f == "Current"){
console.log('c');
headers = ["Won"]
} else if( f == "Projected"){
console.log('p');
headers = ["Won", "Prospecting", "Qualifying", "Demonstrating", "Negotiating"]
}
else {
alert('An error has occured')
};
myTotal = 0;
chunks = (headers.map(function(priceRange) {
return jsonData.map(function(d) {
return {y: +d[priceRange]};
});
}));
var myTarget = 10000000;
chunks.forEach( function (arrayItem)
{
var l = 12;
for(var i = 0; i < l; i++) {
myTotal += arrayItem[i].y;
};
});
myTotal = myTotal/myTarget*100;
gauge5.update(myTotal);
deferred.resolve(myTotal);
});
return true;
}
Now I call GetDataFromJson() directly from a click on a radio button, and pass either "Current" or "Projected" inside that call so the right data is shown. Feels stupid that I've wasted a week studying this, but hopefully this answer will help others. You can't extract data from these promises but you can call another function (in my case gauge5.update) and send it the value you want to use.
You are returning 'data' inside callback, not in function NewValue. NewValue should return promise and caller of NewValue should assign a callback on completion of this promise.
function NewValue(){
var defer = $.Deferred();
var dataPromise = GetDataFromJson();
dataPromise.done(function(data){
//note both console.log(data) and alert(data) deliver the correct result here
deferred.resolve(data);
});
return deferred.promise();
}
NewValue()
.done(function(data){
// do whatever
})
I am assuming you want to process the data further in NewValue function, else why can't you directly call GetDataFromJson?
I have a html page with this javascript in the body section of the page
JSFiddle link (I'm new to jsfiddle, couldn't get it to work, any help on this is appreciated to...)
The Firebug console shows me 0 in request, undefined in onError and 0 in callback. I have two questions, why can't i access this.loadErrors in onError, and how would I implement this error counter?
EDIT: the source code
var loader = new Loader();
loader.request(callback);
function callback(){
console.log("loader.loadErrors in callback: " + loader.loadErrors);
}
function Loader(){
this.loadErrors = 0;
this.request=function(callback){
for (var i = 0; i < 3; i++){
console.log("this.loadErrors in request: " + this.loadErrors);
$.ajax("example", {error: onError}).done(callback);
}
}
function onError(){
console.log("this.loadErrors in onError: " + this.loadErrors);
// this.loadErrors++;
callback();
}
}
The code messed up this keyword.
onError is called from outside of your code and it's this points to an unknown object (probably null).
To prevent this from happening, you have one of the two options:
bind() the onError() function to your Loader before calling it:
this.request=function(callback){
for (var i = 0; i < 3; i++){
console.log("this.loadErrors in request: " + this.loadErrors);
$.ajax("example", {error: onError.bind(this)}).done(callback);
}
}
Bind it to the Loader during creation:
var _this = this;
function onError(){
console.log("this.loadErrors in onError: " + _this.loadErrors);
// _this.loadErrors++;
callback();
}
Update: I read post that this one was flagged as a duplicate of. I generally get how callbacks are supposed to work. My problem is I'm calling the API in a loop that is creating objects, so I can't figure out how to put a callback in there to make the next method wait without calling that callback with each loop iteration.
I created objects and added API data to them. I use a callback so the next bit of code won't run until the API properties are available. The callback is not working.
function Media(boxCover, searchName, year) {
this.boxCover = boxCover;
this.searchName = searchName;
this.year = year;
this.genre = "";
this.imdbRating = "";
apiCall(this);
}
function makeMovieObjects(callback) {
var table = [
new Media('imgs/avengers.jpg', "Avengers", "2012"),
new Media('imgs/blade_runner.jpg', "Blade Runner", "1982")
];
callback(table);
}
function apiCall(obj){
var link = "http://www.omdbapi.com/?t=" + obj.searchName + "&y=" + obj.year + "&plot=short&r=json";
var oReq = new XMLHttpRequest();
oReq.open("get", link, true);
oReq.onload = reqListener;
oReq.send();
function reqListener() {
var apiReturn = JSON.parse(this.response);
obj.genre = apiReturn.Genre;
obj.imdbRating = apiReturn.imdbRating;
}
}
function init(table) {
for (var i = 0; i < table.length; i++) {
console.log(table[i]); // object contains all data
console.log(table[i].genre); // fails (API sourced data)
console.log(table[i].year); // success (data hard coded)
}
}
makeMovieObjects(init(table));
I have an array that I would like to fill with responses from AJAX calls like so:
var dict = [];
function fillArray(){
$.post('getUsersOnline.php', function(phpReturnVal){
// ...
for(var i = 0; i < phpReturnVal.length; i++){
$.get("https://api.twitch.tv/kraken/streams" , function(data){
dict[data.key] = data;
});
});
}
function doStuff(){
// dict is empty or undefined here
}
How would I fill dict with objects so that I could retrieve them inside doStuff()? Currently, I am able to insert stuff into dict but when I try accessing dict outside the fillArray() function, I get an empty dict variable since I'm assuming the GET call is asynchronous and doesn't happen until after all the JS code has executed...
So, dict is an object that has no push method. You'd need dict=[]; If you had to have {}, then you'd need key:value pairs to populate it, such as:
dict[key] = value;
You are going to have to keep track of the number of calls that you are doing in that for loop and fire a callback function once they are all complete. I'm not totally confident about your current solution, with calling an indefinite amount of ajax requests, but I also don't fully understand the scope of your problem or the server that you're talking to.
So basically you will have to do something like this with what you have currently:
var dict = [],
requestsCompleted = 0;
function dictFilled() {
// do something with your dict variable;
}
function fillArray(){
$.post('getUsersOnline.php', function(phpReturnVal){
// ...
for(var i = 0; i < phpReturnVal.length; i++){
$.get("https://api.twitch.tv/kraken/streams" , function(data){
dict[data.key] = data;
requestsCompleted++;
if (requestsCompleted === phpReturnVal.length) {
dictFilled();
}
});
});
}
This haven't been tested, but basically you will have to define a function that will have access to the array that you are filling and call it once all you asynchronous requests finish successfully. For tasks like this though I recommend you take a look at jQuery's Deferred API. There is always a chance that one of those requests will fail and your application should know what to do if that happens.
I'm assuming the GET call is asynchronous and doesn't happen until
after all the JS code has executed...
Appear correct.
Try
var dict = [];
function fillArray() {
// return jQuery promise object
return $.post('getUsersOnline.php', function(phpReturnVal){
// ...
for(var i = 0; i < phpReturnVal.length; i++) {
// call same `url` `phpReturnVal.length` times here ?,
// returning same `data` response at each request ?,
// populating, overwriting `dict` with same `data.key` property ?
$.get("https://api.twitch.tv/kraken/streams" , function(data) {
dict[data.key] = data;
});
}; // note closing `}` at `for` loop
// return value
return dict
});
}
function doStuff(data) {
// `data`:`dict`, promise value returned from `fillArray`
console.log(data);
}
fillArray().then(doStuff, function error(jqxhr, textStatus, errorThrown) {
console.log(textStatus, errorThrown)
});
var arr = ["a", "b", "c"];
var response = {
"a": 1,
"b": 2,
"c": 3
};
var obj = {};
var dict = [];
function fillArray() {
return $.when(arr).then(function(phpReturnVal) {
for (var i = 0; i < phpReturnVal.length; i++) {
// return same `response` here ?
$.when(response).then(function(data) {
dict[arr[i]] = data;
});
};
return dict
});
}
function doStuff(data) {
console.log(data)
}
fillArray().then(doStuff, function error(err) {
console.log(err)
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
if (typeof response == "object") {
store = new dojo.data.ItemFileReadStore({
data : response
});
console.warn("Loaded to Store");
var itemArray = new Array();
var completed = function(items) {
for(var i = 0; i < items.length; i++) {
console.log(store.getValue(items[i],"itemlabel"));
itemArray.push(store.getValue(items[i]));
}
};
var error = function() {
console.log("Error in fetching data from Store");
};
store.fetch({onComplete: completed, onError: error});
console.warn("Item count"+ itemArray.length);
So my Item Count gives Always 0 but
console.log(store.getValue(items[i],"itemlabel"));
In the callback method the above get print the value.
So if i want to populate my itemArray what can i do?
You're printing itemArray.length before the array gets populated with any data in the completed function, because completed will be called asynchronously.
If you want to print the actual length of itemArray, you should do it after the for-loop in completed.
Hello the answer to your problem is quite easy, but first i'd recommand using
var completed = function(items) {
dojo.forEach(items, function(item) {
console.log(store.getValue(items[i],"itemlabel"));
itemArray.push(store.getValue(items[i]));
}, this);
proceedToNextStep(itemArray);
};
and then you create a function that will be used to keep on the process once the itemArray is loaded..
proceedToNextStep: function(itemArray){
// whatever you need to do
},
You could also use dojo.publish / dojo.subscribe