I just set up a cloud function triggered by a sub/pub topic. The function triggers an HTTP-triggered cloud function by, well, making a GET request. It all works well, the only thing that doesn't quite line up is a warning message
Function returned undefined, expected Promise or value
I have to admit I'm not as fluent in promises as I should be, and that might be the reason for the error. Here is the Node code.
exports.triggerClearHidden = functions.runWith(global.runtimeOptions).pubsub.topic('trig').onPublish((message) => {
// const pubsubMessage = message.data;
// console.log(Buffer.from(pubsubMessage, 'base64').toString());
let urlstr = functions.config().rain.projecturl + "/clearHidden";
httpGetAsync(urlstr, (txt => console.log(txt)));
});
function httpGetAsync(theUrl, callback)
{
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState === 4 && xmlHttp.status === 200){
return callback(xmlHttp.responseText);
} else {
return callback("the ready state is " + xmlHttp.readyState + " and the status is " + xmlHttp.status);
}
}
xmlHttp.open("GET", theUrl, true); // true for asynchronous
xmlHttp.send(null);
}
I'm writing an API. I can successfully send data to it in postman by including it in body > form data. However, this code does not send anything as form-data!
addGuild = function () {
req = new XMLHttpRequest();
req.open("GET", "https://gralyn.app/api/server/add/" + window.guild)
formdata = new FormData()
formdata.append('prefix', document.getElementById("install-prefix").value);
req.setRequestHeader("token", this.localStorage.getItem("token"))
req.onreadystatechange = function () {
if (this.readyState == 4) {
if (this.status == 200) {
alert("Success!")
} else {
console.log("ERROR: " + this.status)
openModal("error")
}
}
}
req.send(formdata)
}
The API does not receive a prefix as formdata! I am accessing the prefix in flask via request.form['prefix']
Figured it out, javascript wont allow form data in a GET request.
I'm trying to include an if statement that analyzes the webmethod response which is either true or false. I just want to alert the user the post was successful if the response is true or the post was not successful if the response is false.
I can get the response using xhttp.responseText but I can't figure out how to build that into an if statement inside my javascript below:
//JavaScript that Posts to WebMethod
<script>
function createNewComment() {
var xhttp = new XMLHttpRequest();
var url = "http://localhost:57766/PALWebService.asmx/insertComment"
var a = document.getElementsByName("existingguid")[0].value;
var b = document.getElementsByName("newcomment")[0].value;
var c = 'existingguid=' + a + '&newcomment=' + b;
xhttp.open("POST", url, true);
xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
}
};
xhttp.send(c);
}
</script>
I figured it out. After checking that readyState was 4 and status was 200 I simply nested another if statement to check the responseText from the XMLHttpRequest and it was true I called another function and if it was false I notified user the post failed on the webmethod. It may not be perfect, but it works for what I need.
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
if (xhttp.responseText = true) {
addComment(b, today, userName);
}
else {
document.getElementsByName("newcomment")[0].value = '';
$("#commentLabel").html("Your comment was not saved in the database. Please try again or contact system admin.");
}
}
};
I have a problem with my code and I'm struggling finding why it doesn't work as expected.
I have an API that returns data async. and I want the frontend side to add that data as soon as it's being received. What I expect is an API that returns, say 200 items, then javascript to load those 200 items to a table, meanwhile the API keeps returning another 200 items, and then javascript appends them to the table, and so on until there is no more data left.
I'm using vanilla Javascript 5, prototype-based MVC pattern. Perhaps I'm not getting something simple or its far more complex than I expected.
resultView.js
//this function gets executed by some other code not relevant
ResultView.prototype.execute = function(serverName, databaseName, query){
var response = resultController.getData(serverName, databaseName, query);
console.log("response: ", response); //prints undefined
response.done(function(data){ // Uncaught TypeError: Cannot read property 'done' of undefined
console.log("response done: ", response); //doesn't even execute
data.forEach(populateTable); //this code should populates the table
});
}
resultController.js
ResultController.prototype.getData = function(serverName, databaseName, query){
return resultModel.getData(serverName, databaseName, query);
};
resultModel.js
ResultModel.prototype.getData = function (serverName, databaseName, query) {
var dataSend = {
//the code that is being sent
};
var result = "";
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.onprogress = function () {
result += xhr.responseText;
if(xhr.readyState == 4){
console.log("return: ", result); //shows the results properly each time they are received
return result; //not sure about this return
}
}
xhr.send(JSON.stringify(dataSend));
};
}
I know the data is being received in the API, and the data is returned properly in the front end, the issue must be how I am trying to handle it.
Currently, the results I am getting on the console.log at resultModel.js are the expected, the problem seems to be when calling it from resultView.js, I guess when the function calls response.done(), but I am unable to fix it.
Anyone knows how can I approach a solution?
Thanks in advance.
EDIT:
Partially thanks to Ionut, I've managed to make the resultView.js return better datas, but I still have the problem at the resultView.js, when I try to use response.done(...) it tells me it can't do done() of undefined, but the data should be able to be returned. This is my code in resultModel.js now, the rest remains unchanged.
resultModel.js
var xhr = new XMLHttpRequest();
console.log("Sending the request...");
xhr.open("POST", urlBase + "QueryResults", true);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
console.log("return: ", xhr.responseText); //data is logged properly
return xhr.responseText; //it should be returned properly
}
};
xhr.send(JSON.stringify(queryRequest));
You should add a callback function to manage the full response.
If you want to implement something like lazy-loading you should request your API to send you batches of a smaller number of items, you process them then request more until you get them all.
Here is a basic http request.
console.log('Sending the request ...');
var xhr = new XMLHttpRequest();
xhr.open('GET', "//ipinfo.io/json", true);
xhr.send();
xhr.onreadystatechange = processRequest;
function processRequest(e) {
console.log('Getting the response ...');
if (xhr.readyState == 4 && xhr.status == 200) {
var response = JSON.parse(xhr.responseText);
console.log('Your ip address is ' + response.ip);
} else {
console.log('Error state=' + xhr.readyState + ', status=' + xhr.status);
}
}
I'm trying to make a GET using javascript only (not jQuery, as I am using React) and I'm wondering how to get only the JSON back. Can someone please help? Basically, if I use the postman app and do GET at localhost:3000/api/v1/posts, I am seeing all the posts I have created.
If I can get this into an object, then I can use that later with Object.keys().
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status == 200) {
console.log("success : " + request.responseText);
var mPosts = JSON.parse(request)
} else {
//This would print if something goes wrong along with the error message
console.log("other status : " + request.status + " : " + request.responseText);
}
};
request.open('GET', 'http://localhost:3000/api/v1/posts', true);
request.setRequestHeader('Content-Type', 'application/json');
//need to serialize payload before sending it
request.send();