I am trying to play with tvOS, and I have small question regarding handling json call. I have to get some data through an API, let's say for sake of test that I am calling this link
http://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20location%3D%223015%22&format=json
I tried to use this function with some modification
function getDocument(url) {
var templateXHR = new XMLHttpRequest();
templateXHR.responseType = "json";
templateXHR.open("GET", url, true);
templateXHR.send();
return templateXHR;
}
but didn't work out. Any hints or help ?
If I need to use NodeJS, how can I do that ?
This is one that I got working. It's not ideal in many respects, but shows you something to get started with.
function jsonRequest(options) {
var url = options.url;
var method = options.method || 'GET';
var headers = options.headers || {} ;
var body = options.body || '';
var callback = options.callback || function(err, data) {
console.error("options.callback was missing for this request");
};
if (!url) {
throw 'loadURL requires a url argument';
}
var xhr = new XMLHttpRequest();
xhr.responseType = 'json';
xhr.onreadystatechange = function() {
try {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
callback(null, JSON.parse(xhr.responseText));
} else {
callback(new Error("Error [" + xhr.status + "] making http request: " + url));
}
}
} catch (err) {
console.error('Aborting request ' + url + '. Error: ' + err);
xhr.abort();
callback(new Error("Error making request to: " + url + " error: " + err));
}
};
xhr.open(method, url, true);
Object.keys(headers).forEach(function(key) {
xhr.setRequestHeader(key, headers[key]);
});
xhr.send();
return xhr;
}
And you can call it with the following example:
jsonRequest({
url: 'https://api.github.com/users/staxmanade/repos',
callback: function(err, data) {
console.log(JSON.stringify(data[0], null, ' '));
}
});
Hope this helps.
I tested this one out on the tvOS - works like a charm with jQuery's syntax (basic tests pass):
var $ = {};
$.ajax = function(options) {
var url = options.url;
var type = options.type || 'GET';
var headers = options.headers || {} ;
var body = options.data || null;
var timeout = options.timeout || null;
var success = options.success || function(err, data) {
console.log("options.success was missing for this request");
};
var contentType = options.contentType || 'application/json';
var error = options.error || function(err, data) {
console.log("options.error was missing for this request");
};
if (!url) {
throw 'loadURL requires a url argument';
}
var xhr = new XMLHttpRequest();
xhr.responseType = 'json';
xhr.timeout = timeout;
xhr.onreadystatechange = function() {
try {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
if (xhr.responseType === 'json') {
success(null, xhr.response);
} else {
success(null, JSON.parse(xhr.responseText));
}
} else {
success(new Error("Error [" + xhr.status + "] making http request: " + url));
}
}
} catch (err) {
console.error('Aborting request ' + url + '. Error: ' + err);
xhr.abort();
error(new Error("Error making request to: " + url + " error: " + err));
}
};
xhr.open(type, url, true);
xhr.setRequestHeader("Content-Type", contentType);
xhr.setRequestHeader("Accept", 'application/json, text/javascript, */*');
Object.keys(headers).forEach(function(key) {
xhr.setRequestHeader(key, headers[key]);
});
if(!body) {
xhr.send();
} else {
xhr.send(body);
}
return xhr;
}
Example queries working on Apple TV:
var testPut = function(){
$.ajax({
type: 'PUT',
url: url,
success: successFunc,
error: errFunc,
dataType: 'json',
contentType: 'application/json',
data: data2
});
}
var testGet = function(){
$.ajax({
dataType: 'json',
url: url,
success: successFunc,
error: errFunc,
timeout: 2000
});
}
var getLarge = function(){
$.ajax({
dataType: 'json',
url: url,
success: successFunc,
error: errFunc,
timeout: 2000
});
}
Did you call your function in the 'App.onLaunch'
App.onLaunch = function(options) {
var url = 'http://query.yahooapis.com/v1/public/yql?q=select%20item%20from%20weather.forecast%20where%20location%3D%223015%22&format=json';
var doc = getDocument(url);
console.log(doc);
}
Might be worth looking at https://mathiasbynens.be/notes/xhr-responsetype-json
I came across this question looking to accomplish the same thing, and was inspired by #JasonJerrett's answer, but found it a bit lacking because in my instance I am using an XML template built in Javascript like this:
// Index.xml.js
var Template = function() {
return `very long xml string`;
};
The issue is that you can't perform the XHR request inside the template itself, because the template string will be returned back before the XHR request actually completes (there's no way to return data from inside an asynchronous callback). My solution was to modify the resource loader and perform the XHR request there, prior to calling the template and passing the data into the template function:
ResourceLoader.prototype.loadResource = function(resource, dataEndpoint, callback) {
var self = this;
evaluateScripts([resource], function(success) {
if (success) {
// Here's the magic. Perform the API call and once it's complete,
// call template constructor and pass in API data
self.getJSON(dataEndpoint, function(data) {
var resource = Template.call(self, data);
callback.call(self, resource);
});
} else {
var title = "Failed to load resources",
description = `There was an error attempting to load the resource. \n\n Please try again later.`,
alert = createAlert(title, description);
Presenter.removeLoadingIndicator();
navigationDocument.presentModal(alert);
}
});
}
// From: https://mathiasbynens.be/notes/xhr-responsetype-json
ResourceLoader.prototype.getJSON = function(url, successHandler, errorHandler) {
var xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.onreadystatechange = function() {
var status;
var data;
if (xhr.readyState == 4) {
status = xhr.status;
if (status == 200) {
data = JSON.parse(xhr.responseText);
successHandler && successHandler(data);
} else {
errorHandler && errorHandler(status);
}
}
};
xhr.send();
};
Then the template function needs to be modified to accept the incoming API data as a parameter:
// Index.xml.js
var Template = function(data) {
return 'really long xml string with injected ${data}';
};
You need to implement the onreadystatechange event on the XHR object to handle the response:
templateXHR.onreadystatechange = function() {
var status;
var data;
if (templateXHR.readyState == 4) { //request finished and response is ready
status = templateXHR.status;
if (status == 200) {
data = JSON.parse(templateXHR.responseText);
// pass the data to a handler
} else {
// handle the error
}
}
};
If you want to call the request on app launch, just add in application.js:
App.onLaunch = function(options) {
var javascriptFiles = [
`${options.BASEURL}js/resourceLoader.js`,
`${options.BASEURL}js/presenter.js`
];
evaluateScripts(javascriptFiles, function(success) {
if(success) {
resourceLoader = new ResourceLoader(options.BASEURL);
var index = resourceLoader.loadResource(`${options.BASEURL}templates/weatherTemplate.xml.js`, function(resource) {
var doc = Presenter.makeDocument(resource);
doc.addEventListener("select", Presenter.load.bind(Presenter));
doc.addEventListener('load', Presenter.request);
navigationDocument.pushDocument(doc);
});
} else {
var errorDoc = createAlert("Evaluate Scripts Error", "Error attempting to evaluate external JavaScript files.");
navigationDocument.presentModal(errorDoc);
}
});
}
In presenter.js add a method:
request: function() {
var xmlhttp = new XMLHttpRequest() , method = 'GET' , url = 'your Api url';
xmlhttp.open( method , url , true );
xmlhttp.onreadystatechange = function () {
var status;
var data;
if (xmlhttp.readyState == 4) {
status = xmlhttp.status;
if (status == 200) {
data = JSON.parse(xmlhttp.responseText);
console.log(data);
} else {
var errorDoc = createAlert("Evaluate Scripts Error", "Error attempting to evaluate external JavaScript files.");
navigationDocument.presentModal(errorDoc);
}
}
};
xmlhttp.send();
},
Related
I did a function to show a div when i open my html(its working fine, the div shows at open), but i get this error:
var getJSON = function (url, callback) {
var ajax = new XMLHttpRequest();
ajax.open('GET', url, true);
ajax.responseType = 'json';
ajax.onreadystatechange = function () {
var status = ajax.status;
if (status === 200) {
callback(status, ajax.response);
} else {
callback(null, ajax.response);
}
};
ajax.send();
};
getJSON('games.json', function (err, data) {
if (err === null) {
console.log('Error' + err);
} else {
var bets = document.getElementById('bets-container-lotos');
bets.innerHTML = '';
bets.innerHTML +=
'<button id="bets-lotofacil-color" class="bets-lotofacil" onclick=lotofacil()>' +
data.types[0].type +
'</button>';
}
});
I would like to port this open source Python library for Google Reminders to JavaScript:
https://github.com/jonahar/google-reminders-cli
I have ported the authorization with the help of https://developers.google.com/identity/protocols/OAuth2UserAgent
My JavaScript version: https://github.com/Jinjinov/google-reminders-js
Now I need to port the Python's oauth2client POST request:
body = {
'5': 1, # boolean field: 0 or 1. 0 doesn't work ¯\_(ツ)_/¯
'6': num_reminders, # number number of reminders to retrieve
}
HEADERS = {
'content-type': 'application/json+protobuf',
}
response, content = self.auth_http.request(
uri='https://reminders-pa.clients6.google.com/v1internalOP/reminders/list',
method='POST',
body=json.dumps(body),
headers=HEADERS,
)
My XMLHttpRequest POST request returns:
HTTP 400 - Bad Request - if I use 'application/x-www-form-urlencoded'
HTTP 401 - Unauthorized - if I use 'application/json'
My code (full code with authorization and access token is on GitHub):
function encodeObject(params) {
var query = [];
for (let key in params) {
let val = encodeURIComponent(key) + "=" + encodeURIComponent(params[key]);
query.push(val);
}
return query.join('&');
}
function list_reminders(num_reminders, access_token, callback) {
var body = {
'5': 1, // boolean field: 0 or 1. 0 doesn't work ¯\_(ツ)_/¯
'6': num_reminders, // number of reminders to retrieve
};
body['access_token'] = access_token;
//body = JSON.stringify(body);
body = encodeObject(body);
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://reminders-pa.clients6.google.com/v1internalOP/reminders/list' + '?' + body);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
//xhr.open('POST', 'https://reminders-pa.clients6.google.com/v1internalOP/reminders/list');
//xhr.setRequestHeader('Content-type', 'application/json');
xhr.onreadystatechange = function (e) {
if (xhr.readyState === 4 && xhr.status === 200) {
var content_dict = JSON.parse(xhr.response);
if (!('1' in content_dict)) {
console.log('No reminders found');
}
else {
var reminders_dict_list = content_dict['1'];
var reminders = [];
for(var reminder_dict of reminders_dict_list) {
reminders.push(build_reminder(reminder_dict));
}
callback(reminders);
}
}
else if (xhr.readyState === 4 && xhr.status === 401) {
callback(null);
}
}
//xhr.send(body);
xhr.send(null);
}
I was trying to send both, the body and the access token in the same way.
The solution is to send the access token as url encoded and the body as json:
function list_reminders(num_reminders, access_token, callback) {
/*
returns a list of the last num_reminders created reminders, or
None if an error occurred
*/
var xhr = new XMLHttpRequest();
xhr.open('POST', 'https://reminders-pa.clients6.google.com/v1internalOP/reminders/list' + '?' + 'access_token=' + access_token);
xhr.setRequestHeader('Content-type', 'application/json+protobuf');
xhr.onreadystatechange = function (e) {
if (xhr.readyState === 4 && xhr.status === 200) {
var content_dict = JSON.parse(xhr.response);
if (!('1' in content_dict)) {
console.log('No reminders found');
}
else {
var reminders_dict_list = content_dict['1'];
var reminders = [];
for(var reminder_dict of reminders_dict_list) {
reminders.push(build_reminder(reminder_dict));
}
callback(reminders);
}
}
else if (xhr.readyState === 4 && xhr.status === 401) {
callback(null);
}
}
var body = {
'5': 1, // boolean field: 0 or 1. 0 doesn't work ¯\_(ツ)_/¯
'6': num_reminders, // number of reminders to retrieve
};
xhr.send(JSON.stringify(body));
}
I'm trying to add Ajax like beforeSend function to my XMLHttpRequest. I'm getting following error:
TypeError: Cannot read property 'type' of undefined
Here is my code:
var csrftoken = jQuery("[name=csrfmiddlewaretoken]").val();
function csrfSafeMethod(method) {
// these HTTP methods do not require CSRF protection
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
}
function beforeSend(xhr, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
xhr.setRequestHeader("X-CSRFToken", csrftoken);
}
}
var http = new XMLHttpRequest();
http.open('POST', messageEndpoint, true);
http.setRequestHeader('Content-type', 'application/json');
http.onreadystatechange = function() {
if (http.readyState === 4 && http.status === 200 && http.responseText) {
Api.setResponsePayload(http.responseText);
}
};
var params = JSON.stringify(payloadToWatson);
if (Object.getOwnPropertyNames(payloadToWatson).length !== 0) {
Api.setRequestPayload(params);
}
// Added beforeSend() function before sending the params
beforeSend();
http.send(params);
I notice your using jQuery... then you can use $ajax method; here an example
$ajax({
url: 'yourURLhere',
data: {some: 'value'},//{} or [] or ""
method: 'POST',
beforeSend: function(jqXHR, settings) {
// do something
},
success: function(data) {
},
error: function(err) {
}
})
Anyone who was in my situation and trying to send csrf token with XMLHttpRequest request. Here is how I solved it:
Create csrf token:
var csrfcookie = function() {
var cookieValue = null,
name = 'csrftoken';
if (document.cookie && document.cookie !== '') {
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
var cookie = cookies[i].trim();
if (cookie.substring(0, name.length + 1) == (name + '=')) {
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
break;
}
}
}
return cookieValue;
};
Build http request:
var http = new XMLHttpRequest();
http.open('POST', messageEndpoint, true);
http.setRequestHeader('X-CSRFToken', csrfcookie());
I observed a very strange behavior. If I set a button from web to upload string to S3, it works fine. But if I set a button from web to bring up a bootstrap modal, then from this modal I set a button to upload the string, it doesn't work.
Frontend is like below in both cases. The difference is whether clicking to run function 'saveToAWS' from web or from modal as 2-step-process, the latter returns xhr.status as 0.
function saveToAWS() {
var file = new File([jsonStr], "file.json", { type: "application/json" });
var xhr = new XMLHttpRequest();
var fn=file.name;
var ft = file.type;
xhr.open("GET", "/sign_s3_save?file-name=" + fn + "&file-type=" + ft);
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
var response = JSON.parse(xhr.responseText);
console.log('signiture returned')
save_file(file, response.signed_request, response.url);
}
else {
alert("Could not get signed URL.");
}
}
};
xhr.send();
}
function save_file(file, signed_request, url) {
var xhr = new XMLHttpRequest();
xhr.open('PUT', signed_request);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
console.log('200');
}
else {
alert('cannot upload file');
}
}
};
xhr.send(file);
}
Backend as Node.js, in order to get a signed URL:
app.get('/sign_s3_save', isLoggedIn, function (req, res) {
var fileName = req.query['file-name'];
var fileType = req.query['file-type'];
aws.config.update({ accessKeyId: AWS_ACCESS_KEY, secretAccessKey: AWS_SECRET_KEY });
var s3 = new aws.S3();
var ac = req.user._id;
var timenow = Date.now().toString();
var fileRename = ac + '/json/' + timenow + '.json';
var s3_params = {
Bucket: S3_BUCKET,
Key: fileRename,
Expires: 60,
ContentType: fileType,
ACL: 'public-read'
};
s3.getSignedUrl('putObject', s3_params, function (err, data) {
if (err) {
console.log(err);
}
else {
var return_data = {
signed_request: data,
url: 'https://' + S3_BUCKET + '.s3.amazonaws.com/' + fileRename
};
res.write(JSON.stringify(return_data));
res.end();
}
});
});
Any suggestion, please?
I am at basic level of application development.
I wanted to know how I can send and get this data with JQuery any new version.
I also want it to support all browsers.
I'm just using simple Ajax but I know it is possible with Jquery and im not able to figure it out.
function SendData() {
var data = "action=check&uid=" + uid + "&fbuid=" + fb_uid + ";
var url = "http://www.example.com/call.php";
var ajax = new AJAXInteraction(url, CheckRate);
ajax.doPost(data);
};
function CheckRate(Content) {
response = JSON.parse(Content);
Rate = response.stat.rate;
document['getElementById']('ERate')['value'] = Rate;
};
function AJAXInteraction(url, callback) {
var req = init();
req.onreadystatechange = processRequest;
function init() {
if (window.XMLHttpRequest) {
return new XMLHttpRequest();
}
else if (window.ActiveXObject) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
function processRequest() {
if (req.readyState == 4) {
if (req.status == 200) {
if (callback) callback(req.responseText);
}
}
}
this.doGet = function () {
req.open("GET", url, true);
req.send(null);
}
this.doPost = function (str) {
req.open("POST", url, true);
req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
req.send(str);
}
};
I am able to solve first part And still dont know rest:
function SendData(){
dataString = "action=check&uid=" + uid + "&fbuid=" + fb_uid + ";
url = "http://www.example.com/call.php";
jQuery.ajax({
type: "POST",
url: url,
data: dataString,
});
};
My problem is how i will read response
function CheckRate(Content) {
response = JSON.parse(Content);
Rate = response.stat.rate;
document['getElementById']('ERate')['value'] = Rate;
};
function SendData() {
dataString = "action=check&uid=" + uid + "&fbuid=" + fb_uid + ";
url = "http://www.example.com/call.php";
jQuery.ajax({
type: "POST",
url: url,
data: dataString, // sending data
success: function (data) {
CheckRate(data); // receiving data
}
});
};
// function body should looks like this
function CheckRate(Content) {
response = JSON.parse(Content);
Rate = response.stat.rate;
document['getElementById']('ERate')['value'] = Rate;
};