Callback from API - javascript

I have the following script on http://foobar.com/api?callback=mycallback:
var something = 'aaa';
var callback = mycallback;
(function() {
var output = eval(something);
callback(output);
});
And I want to access this script from my own script, and fetch the output. So I am doing the following:
var module1 = (function() {
var getFromApi = function(output) {
return (function(output) {
var script = document.createElement('script');
script.setAttribute('src', 'http://foobar.com/api?callback=mycallback');
document.getElementsByTagName('head')[0].appendChild(script);
});
};
var fetch = function() {
getFromApi(function(output) {
console.log(output);
});
};
return {
fetch: fetch
};
})();
module1.fetch();
The result should be the output from this script, but it is not, it doesn't even enters the callback. How can I do this properly?

There are some problems in module1:
getFromApi returns a function (let's call it fn)
fn has a parameter named output that shadows the argument of the outer function making the argument passed to getFromApi useless
fetch calls getFromApi and it does nothing else
the callback function must be globally accessible
A possible solution could be:
var module1 = (function() {
var getFromApi = function(output) {
var script = document.createElement('script');
script.setAttribute('src', 'http://foobar.com/api?callback='+output);
document.getElementsByTagName('head')[0].appendChild(script);
};
var fetch = function() {
getFromApi('myfunction');
};
return {
fetch: fetch
};
})();
function myfunction(output) {
console.log(output);
}
module1.fetch();
Possible nasty solution for function as callback (It will not work in IE but can be adapted)
var module1 = (function() {
var getFromApi = function(output) {
var script = document.createElement('script');
script.setAttribute('src', 'http://foobar.com/api?callback=eval(document.currentScript.dataset.fn)');
script.setAttribute('data-fn', '(function(){ return ' + output +'})()');
document.getElementsByTagName('head')[0].appendChild(script);
};
var fetch = function() {
return getFromApi(function(output){
console.log(output);
/*remember to remove script tag*/
document.currentScript.remove();
});
};
return {
fetch: fetch
};
})();
module1.fetch();

Related

How to preload JSON link?

I've got a function that needs to call a link (JSON format), the fact is that I would like to be able to preload this link to smooth and reduce the operation time when calling the function.
onSelectionChanged: function (selectedItems) {
selectedItems.selectedRowsData.forEach(function(data) {
if(data) {
colorMe(data.target)
}
});
}
function colorMe(item){
globalItem = item;
request('http://blablabla/?format=json',findMaterial);
};
function findMaterial(data){
jq310.each(data, function(table) {
if (data[table].identifier == globalItem){
globalData = data[table]
request('http://another-blablabla/?format=json',findMatchArea);
};
});
};
function findMatchArea(areas){
jq310.each(areas, function(area) {
blablabla
The request function that I built just look if the link as been already called, so it's reloading it if true. And also send data from the link to the called function.
If you'r looking to load a static json file you should concider loading it on the top of your file. To do so you should store the datas in a global variable like that :
let datas;
request('http://blablabla/?format=json', (data) => {
datas = data
});
onSelectionChanged: function (selectedItems) {
selectedItems.selectedRowsData.forEach(function(data) {
if(data) {
globalItem = data.target;
findMaterial();
}
});
}
function colorMe(item){
globalItem = item;
};
function findMaterial(){
const data = datas;
jq310.each(data, function(table) {
if (data[table].identifier == globalItem){
globalData = data[table]
request('http://another-blablabla/?format=json',findMatchArea);
};
});
};
I finally found a way to do it properly, here it is :
var mylink = 'https://fr.wikipedia.org/wiki/JavaScript';
function preloadURL(link){
var xhReq = new XMLHttpRequest();
xhReq.open("GET", link, false);
xhReq.send(null);
var jsonObject = JSON.parse(xhReq.responseText);
return jsonObject;
};
jsonObjectInv = preloadURL(mylink);
And I just point to my json variable to parse it (really faster)
function colorMe(item){
globalItem = item;
findMaterial(jsonObjectInv);
};
Problem solved

Assign asynchronous jsonp result to a variable

I have an asynchronous jsonp-Call and try to assign the result to the variable "FILL_ME" in the example below.
The onSuccess function is called successful, nevertheless it is not possible to assign it's value to the variable "FILL_ME". Instead the error is thrown: Uncaught TypeError: Cannot read property '0' of undefined, which seems like a scope issue.
Please have a look at the following code.
The console.log("final " +FILL_ME) is triggered before the onSuccess method.
How would I assign the result to a variable?
function foo() {
var FILL_ME = 'OVERWRITE ME';
var $jsonp = (function() {
var that = {};
that.send = function(src, options) {
var callback_name = options.callbackName || 'jsonCallback',
on_success = options.onSuccess || function() {},
on_timeout = options.onTimeout || function() {},
timeout = options.timeout || 10; // sec
var timeout_trigger = window.setTimeout(function() {
window[callback_name] = function() {};
on_timeout();
}, timeout * 1000);
window[callback_name] = function(data) {
window.clearTimeout(timeout_trigger);
on_success(data);
}
var script = document.createElement('script');
script.type = 'text/javascript';
script.async = true;
script.src = src;
document.getElementsByTagName('head')[0].appendChild(script);
}
return that;
})();
$jsonp.send('https://run.plnkr.co/plunks/v8xyYN64V4nqCshgjKms/data-2.json', {
callbackName: 'jsonCallback',
onSuccess: function(json) {
console.log('onSuccess!' +json);
FILL_ME = json["sites"][0]["siteName"];
console.log(FILL_ME);
},
onTimeout: function() {
console.log('onTimeout!');
FILL_ME = '';
console.log(FILL_ME);
},
timeout: 5
});
console.log("final " +FILL_ME)
}
<body onLoad="foo()">
</body>
Cannot read property '0' of undefined
is referring to where you try to access the data returned from your jsonp call, specifically where you try to access property 0 of the array:
json["sites "][0]["siteName"];
That means that json["sites "] is undefined. Likely because of the extra space after sites. It seems to work correctly if you remove that space:
http://plnkr.co/edit/UpGMxruppHeh1U8x0j7B
If you want to use the variable outside of your onSuccess callback, you'll have to write another method you call and pass in FILL_ME like so:
function runAfterSuccess(p_FILL_ME) {
console.log("Here I can do whatever I want with FILL_ME", p_FILL_ME);
}
Then in your onSuccess callback use:
runAfterSuccess(FILL_ME);

used instant variable inside the object define function

i need to used instant variable inside the object define function like that .
i need to use Result variable outside the function
function Request(params,type,url){
var loginReq = Titanium.Network.createHTTPClient();
loginReq.open(type,url);
loginReq.setRequestHeader("Content-Type", "application/json; charset=utf-8");
loginReq.setRequestHeader("enctype", "multipart/form-data");
loginReq.setRequestHeader("Content-Type", "image/png;charset=utf-8");
loginReq.send(params);
loginReq.onload = function()
{
var json = this.responseText;
var Result = JSON.parse(json);
};
return Result;
};
exports.Request = Request;
i need to return Result Or use it outside the scope.
You need to use either a callback, or a promise library
Using a callback
function Request(params,type,url,callback){
//...
loginReq.onload = function() {
var json = this.responseText;
var Result = JSON.parse(json);
callback(Result);
};
};
//Somewhere else
Request(/**/,/**/,/**/,function(result){
//use result
});
Using a promise library like Q
var Q = require("q");
function Request(params,type,url,callback){
var deferred = Q.defer();
//...
loginReq.onload = function() {
var json = this.responseText;
var Result = JSON.parse(json);
deferred.resolve(Result);
};
return deferred.promise;
};
//Somewhere else
Request(/**/,/**/,/**/).then(function(result){
//use result
});

handlebar.js helpers with asynchronous data

I wonder how to work with sync data and handlebar helpers. I want to load cms messages to a single page application and I tried out following method and could not able to achieve it.
Please see following code.
function loadCmsMessage(key) {
var cms = {
"msg.001": "Hello {0} {1}"
};
var deferred = $.Deferred();
setTimeout(function () {
var msg = cms[key];
deferred.resolve(msg);
}, 1000);
return deferred.promise();
}
Handlebars.registerHelper('cms', function (key, arr) {
var promise = loadCmsMessage(key);
promise.done(function (str) {
str = Handlebars.Utils.escapeExpression(str);
if ($.isArray(arr)) {
$.each(arr, function (i) {
var safeStr = Handlebars.Utils.escapeExpression(arr[i]);
str = str.replace("{" + i + "}", safeStr);
});
}
var result = '<span class="cms-data">' + str + '</span>';
return new Handlebars.SafeString(result);
});
});
$(document).ready(function () {
var template = Handlebars.compile($("#myTemplate").html());
$("#wrap").html(template({
"person": ['Jane', 'Fonda']
}));
});
You can't. The return statement is at the inner function of the Promise. Handlebars helpers don't allow asynchronousness.

How to use YAHOO.util.Connect.asyncRequest and return results?

I'm using YAHOO.util.Connect.asyncRequest to get data from database, here is the code :
function getCountArticle(contentCurValue) {
var handleSuccess = function (res) {
var countPubmed = YAHOO.lang.JSON.parse(res.responseText);
var contentCountPubmed = countPubmed.totalArticleRecords;
alert(contentCountPubmed); //return 15 for example
};
var handleFailure = function () {
alert("Error connecting data : Bad pubmed query");
};
var callback =
{
success:handleSuccess,
failure:handleFailure,
timeout: 5000
};
var sURL = 'qct-list-article.html?term=' + contentCurValue + '&retstart=0' + '&retmax=1';
var request = YAHOO.util.Connect.asyncRequest('GET',sURL,callback);
}
I would like this function return : "contentCurValue" (eg:15), but when I try to use this code I get "undefined" :
var test = getCountArticle();
alert(test); // return undefined, should return 15
My error is probably due to asynchronous query, but how can I force "var test = getCountArticle();" to wait for results ?
Since the call is by nature asynchronous, rather than try to wait for the response, you would be better off specifying a callback function to execute with the data. You could modify your method like this:
function getCountArticle(contentCurValue, callback) {
var handleSuccess = function (res) {
var countPubmed = YAHOO.lang.JSON.parse(res.responseText);
var contentCountPubmed = countPubmed.totalArticleRecords;
callback(contentCountPubmed); //return 15 for example
};
// ...
}
then your calling code would be:
getCountArticle("contentCurValue", function(test) {
alert(test);
});
Any further execution using the value returned from your AJAX query would proceed inside of your callback method.
This SO post is essentially the same problem, but not YUI specific: Getting undefined in javascript when calling ajax

Categories

Resources