JavaScript sql.js - is callback correct? - javascript

So i keep getting [object Object] where actually the result of a query should be. My question is, whether my callback is incorrect, because I have a hard time understanding it, but think i did it correct.
HTML-part:
<button type="button" id="input_search" onclick="getSearchFromSQL()">Search</button>
JS-part:
function getSearchFromSQL() {
document.getElementById('output').innerHTML = contents;
}
getSearchAsync(function (result) {
contents = result;
});
function getSearchAsync(callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', 'test123.sqlite3', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function (e) {
var uInt8Array = new Uint8Array(this.response);
db = new SQL.Database(uInt8Array);
callback(db.exec("SELECT * FROM data"));
};
xhr.send();
}
I want to add, that my IDE tells me, that "SQL" is not declared as a global variable - not sure if there is a problem, since sql.js is implemented in the html-file.

Related

Passing extra arguments to XMLHttpRequest.onload

I'm trying to comunicate with a server, using XMLHttpRequest in javascript.
How can I pass info to the onload function?
// global variable that containts server response
var reply;
var makeRequest = function(extraInfo) {
var request = new XMLHttpRequest();
request.open(...);
request.onload = handler;
};
var handler = function(data) {
reply = data.target.response;
console.log("Server Reply: " + reply);
};
How can I pass the parameter extraInfo from makeRequest to the handler function? (without using a global variable)
Just use a closure in such way:
...
var makeRequest = function(extraInfo) {
var request = new XMLHttpRequest();
request.open(...);
request.onload = function(data) {
// extraInfo is accessible here
reply = data.target.response;
console.log("Server Reply: " + reply);
};
};
I figured out that passing extra info into the request handler can be done this way: (At least is good for me)
request.open(...);
request.extraInfo = identifier;
request.onload = function() {
identifier = this.extraInfo;
};
The accepted solution didn't work for me, but this did
const params = new FormData();
params.append('selectedValue', selectedValue);
const xhr = new XMLHttpRequest();
xhr.open('post', url, true);
xhr.send(params);
xhr.extraInfo = extraInfo; // <- set your data here
xhr.onload = (e) => {
const data = JSON.parse(xhr.responseText);
alert(xhr.extraInfo) /// <- access it like this
alert(e.target.extraInfo) // <- or like this
//return data;
};

Javascript return after XMLHTTPRequest()

I have this problem, so I want to return the value received after an XMLHTTPRequest(), is this possible? If not, how would I go about achieving the same general idea? Here's what I have so far (It is obviously not working).
function something(url) {
var temp = getPage(url);
console.log(temp);
}
function getPage(url) {
var x = new XMLHTTPRequest();
x.onload = function() {
var html = x.responseText;
//CODE TO PARSE HTML TEXT
var variable = SOMETHING PARSED FROM HTML
return variable;
}
x.open("GET", url);
x.send();
}
This is the programming paradigm that every new javascript developer has to deal with.
Because of the asynchronous nature of javascript, functions tend not to pass values back via return statements, but instead the values are passed back via callback methods.
function something(url) {
getPage(url, function(temp) {
console.log(temp);
});
}
function getPage(url, callback) {
var x = new XMLHTTPRequest();
x.onload = function() {
var html = x.responseText;
//CODE TO PARSE HTML TEXT
var variable = SOMETHING PARSED FROM HTML
callback(variable);
}
x.open("GET", url);
x.send();
}

Turn XMLhttpRequest into a function fails: asynchronity or other?

I try to turn an XMLHttpRequest into a function such
var getImageBase64 = function (url) { // code function
var xhr = new XMLHttpRequest(url);
... // code to load file
... // code to convert data to base64
return wanted_result; // return result of conversion
}
var newData = getImageBase64('http://fiddle.jshell.net/img/logo.png'); // function call
doSomethingWithData($("#hook"), newData); // reinjecting newData in wanted place.
I'am successful to load the file, and to convert to base64. I'am however consistenly failling to get the result as an output :
var getImageBase64 = function (url) {
// 1. Loading file from url:
var xhr = new XMLHttpRequest(url);
xhr.open('GET', url, true); // url is the url of a PNG image.
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
if (this.status == 200) { // 2. When loaded, do:
console.log("1:Response?> " + this.response); // print-check xhr response
var imgBase64 = converterEngine(this.response); // converter
}
}
xhr.send();
return xhr.onload(); // <fails> to get imgBase64 value as the function's result.
}
console.log("4>>> " + getImageBase64('http://fiddle.jshell.net/img/logo.png') ) // THIS SHOULD PRINT THE BASE64 CODE (returned resukt of the function getImageBase64)
See Fiddle here.
How to make it works so it return the new data as output ?
Solution: my final implementation is visible here, and on JS: how to load a bitmap image and get its base64 code?.
Asynchronous calls in JavaScript (like xhr) can't return values like regular functions. The common pattern used when writing asynchronous functions is this:
function asyncFunc(param1, param2, callback) {
var result = doSomething();
callback(result);
}
asyncFunc('foo', 'bar', function(result) {
// result is what you want
});
So your example translated looks like this:
var getImageBase64 = function (url, callback) {
var xhr = new XMLHttpRequest(url);
... // code to load file
... // code to convert data to base64
callback(wanted_result);
}
getImageBase64('http://fiddle.jshell.net/img/logo.png', function(newData) {
doSomethingWithData($("#hook"), newData);
});
When you use xhr.onload your actually defining a function for JS to call when it loads, hence the value of xhr.onload is the function not the output of the function. Returning xhr.onload() will call that function and return the output, but your onload function has no return statement and hence no output. Additionally you are calling xhr.onload synchronously as you set up the object, and hence it won't have any data to process.
I suggest you add a callback parameter to your function like so, this will execute when the data has loaded.
function getImageBase64( url, callback) {
// 1. Loading file from url:
var xhr = new XMLHttpRequest(url);
xhr.open('GET', url, true); // url is the url of a PNG image.
xhr.responseType = 'arraybuffer';
xhr.callback = callback;
xhr.onload = function(e) {
if (this.status == 200) { // 2. When loaded, do:
console.log("1:Response?> " + this.response); // print-check xhr response
var imgBase64 = converterEngine(this.response); // converter
this.callback(imgBase64);//execute callback function with data
}
}
xhr.send();
}
Then you would use it like so
var myCallBack = function(data){
alert(data);
};
getImageBase64('http://fiddle.jshell.net/img/logo.png', myCallBack);

Variable undefined in XMLHTTPResponse.onload scope

This is most likely something I'm overlooking but I can't figure out exactly what the issue is in this situation.
Upload: function (callback) {
var formData, xhr, file,
xhrLoaded = function () {
if (callback) {
callback(this.status, this.response, file);
}
};
if (this._files.length < 1) {
return false;
}
file = this._files.pop();
while (file) {
formData = new FormData();
formData.append("file", file);
xhr = new XMLHttpRequest();
xhr.open("POST", this.options.uploadUrl);
xhr.onload = xhrLoaded;
xhr.send(formData);
file = this._files.pop();
}
}
Why is it the case that when the xhr onload event handler runs file is undefined? At first I thought it was because onload is getting called out of the current scope, but that didn't seem right based on my understanding of javascript scoping. So as a test I checked this on a simple page.
(function () {
var test = "This is a test", testFunc = function () { console.log(test); };
window.onload = testFunc;
})();
and the variable test has the correct value. This tells me it has something to do with the file variable changing. So tried to add var localFile = file to the xhrLoaded method to see if it would keep the correct value in that case but it doesn't appear to be the case.

Can't pass a DOM element to a constructor function in Javascript when trying to abstract section of WebAudio API xhr request

My problem is this. When I add an argument to the audioBoing function below and then place the same argument in the getElementById string, the function doesn't work. I get an error that says uncaught type error, cannot call method 'AddEventListener' of null
The function below works fine. I rewrote the function below it to reflect what I'm trying to do. Ultimately I am trying to abstract a good portion of the function so I can just plug in arguments and run it without having to rewrite it each time for each sound it stores / launches.
var playAudioFileOneDrumOneBig = function () {
var source = context.createBufferSource();
source.buffer = savedBufferOne;
source.connect(delay.input);
delay.connect(convolver.input);
convolver.connect(context.destination);
source.noteOn(0); // Play sound immediately
};
function audioBoing()
var xhr = new XMLHttpRequest();
xhr.open('get', 'audio/F.mp3', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
context.decodeAudioData(xhr.response,
function(incomingBuffer1) {
savedBufferOne = incomingBuffer1;
var noteOneDrumOneBig = document.getElementById("noteOneDrumOneBig");
noteOneDrumOneBig.addEventListener("click", playAudioFileOneDrumOneBig , false);
}
);
};
xhr.send();
};
audioBoing();
ReWritten non-working
function audioBoing(yay) { //added yay
this.yay=yay; // defined yay
var xhr = new XMLHttpRequest();
xhr.open('get', 'audio/F.mp3', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function () {
context.decodeAudioData(xhr.response,
function(incomingBuffer1) {
savedBufferOne = incomingBuffer1;
var noteOneDrumOneBig = document.getElementById(yay); //passed yay
noteOneDrumOneBig.addEventListener("click", playAudioFileOneDrumOneBig , false); //error happens here
}
);
};
xhr.send();
};
audioBoing(noteOneDrumOneBig);
You didn't quote the string you passed to audioBoing
audioBoing("noteOneDrumOneBig");

Categories