How to pass internal function values as parameters to its callback - javascript

Im sorry I don't know the exact wording so please bear with me. what Im trying to do is the same thing as we all do with the event listeners like so:
foo.addEventListener('click', function(event) {
console.log(event.target)
})
with the example above I can access the event instance using the anonymous callback function. in my case, I have this simple function:
function post_rqst({ url, data = '', callback }) {
let request = new XMLHttpRequest();
request.open("POST", url, true);
request.onload = function() {
callback()
}
request.send(data)
}
now when I call the post_rqst(), I want to be able to access the request instance inside the callback definition like so:
post_rqst({
url: 'foo.com/bar/',
data: '[x,y,z]',
callback: function(request) {
if (request.status === 200) {
console.log('done!')
}
}
})
Im a javascript newbie and I don't know what I don't know. thank you for your guidance in advance.

You can just pass that request instance when you call callback, so instead of:
function post_rqst({ url, data = '', callback }) {
let request = new XMLHttpRequest();
request.open("POST", url, true);
request.onload = function() {
callback();
};
request.send(data);
}
You would have:
function post_rqst({ url, data = '', callback }) {
let request = new XMLHttpRequest();
request.open("POST", url, true);
request.onload = function() {
callback(request);
};
request.send(data);
}
Here you can see that in action using setTimeout to fake that request:
function fakePost({ url, data = '', callback }) {
const request = { url, data, method: 'POST' };
setTimeout(() => {
callback(request);
}, 1000);
}
fakePost({
url: 'https://stackoverflow.com/',
data: 'foobar',
origin: 'https://stackoverflow.com/',
callback: (req) => {
console.log('Callback received req =', req);
},
});

Related

AJAX: Posts are sent empty

I am using AJAX for the first time and try to send data to my PHP controller with an XMLHttpRequest. Unfortunately, the data arrives empty there.
request.onload = () => {
let responseObject = null;
try {
responseObject = JSON.parse(request.responseText);
} catch (e) {
console.error('Could not parse JSON!');
}
if (responseObject) {
handleResponse(responseObject);
}
};
const requestData = `title=${this._title.value}&reference=${this._reference.value}&area=${this._area.value}`;
request.open('post', 'checknews');
request.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
request.send(requestData);
Whats wrong ?

Outer function being called before xmlhttprequest being done

room.onPlayerChat is an outer event i have no control on it, When i try to use it i need to process something on message and checking player role through xmlhttprequest and wait for response then send message to room chat but it doesn't wait for it(xmlhttprequest) to return the player's role and send the normal message (normal player role), how to hang that outer event (room.onPlayerChat) and its needed to handle any room chat source.
const makeRequest = (method, url, data = {}) => {
const xhr = new XMLHttpRequest();
return new Promise(resolve => {
xhr.open(method, url, true);
xhr.onload = () => resolve({
status: xhr.status,
response: xhr.responseText
});
xhr.onerror = () => resolve({
status: xhr.status,
response: xhr.responseText
});
if (method != 'GET') xhr.setRequestHeader('Content-Type', 'application/json');
data != {} ? xhr.send(JSON.stringify(data)) : xhr.send();
})
}
room.onPlayerChat = async function (player,message) {
let request = await makeRequest("GET", 'URL/TO/CHECK/PLAYER/ADMIN/ROLE' + player.name);
if (request.response == "YES")
{
room.sendmessage("ADMIN" + player.name + message);
return false;
}
}

Cannot append data to Js FormData

First of all sorry for my English I am trying to send an ajax request. I am using FormData. But when I append data then console.log that format it says no properties. FormData constructor accepts form as a parameter if i am not wrong. Here I used that argument, but also when i use formdata.append(key, value) this is not working also
Here is my code (No Jquery used $.ajax is my self written library).
onValidated: function(form){
var formData = new FormData(form);
console.log(formData);
$.ajax({
url: '/comment/send',
type: 'POST',
contentType: 'application/json',
dataContent: formData,
start: function()
{
$preloader.show();
},
success: function(response)
{
$preloader.hide();
},
error: function(response)
{
return false;
}
});
}
And here is my $.ajax function
window.$.ajax = function(settings)
{
var request;
if (window.XMLHttpRequest)
{
request = new XMLHttpRequest();
}
else{
request = new ActiveXObject("Microsoft.XMLHTTP")
}
request.open(settings.type, settings.url, true);
request.setRequestHeader('Content-Type', settings.contentType);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
settings.success(JSON.parse(request.responseText));
}
};
request.onerror = function() {
settings.error();
}
console.log(settings.dataContent);
// Used for preloader or something else
settings.start();
if (settings.type == 'POST')
{
request.send(settings.dataContent);
}
else if(settings.type == 'GET')
{
request.send();
}
else
{
return false;
}
}

415 (Unsupported Media Type) Error

On my MVC project, I have a POST request to a Web API using XmlHttpRequest.
I send an array of documents' routes in a JSON format and expecting to get from the server a Zip file (ArrayBuffer).
self.zipDocs = function (docs, callback) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {//Call a function when the state changes.
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseBody);
}
}
xhr.open("POST", '../API/documents/zip', true);
xhr.setRequestHeader("Content-type", "application/json");
xhr.responseType = "arraybuffer";
console.log(docs);
xhr.send(docs);
var arraybuffer = xhr.response;
var blob = new Blob([arraybuffer], { type: "application/zip" });
saveAs(blob, "example.zip");
}
And my ZipDocs function on the WebAPI (using the DotNetZip library):
[HttpPost]
[Route("documents/zip")]
public HttpResponseMessage ZipDocs([FromBody] string[] docs)
{
using (var zipFile = new ZipFile())
{
zipFile.AddFiles(docs, false, "");
return ZipContentResult(zipFile);
}
}
protected HttpResponseMessage ZipContentResult(ZipFile zipFile)
{
// inspired from http://stackoverflow.com/a/16171977/92756
var pushStreamContent = new PushStreamContent((stream, content, context) =>
{
zipFile.Save(stream);
stream.Close(); // After save we close the stream to signal that we are done writing.
}, "application/zip");
return new HttpResponseMessage(HttpStatusCode.OK) { Content = pushStreamContent };
}
But the response I'm getting from the server is:
POST http://localhost:1234/MyProject/API/documents/zip 415 (Unsupported Media Type)
Why is this happening, and how do I fix it?
Based on this post
You might want to try
xhr.setRequestHeader("Accept", "application/json");
And your code is missing a semicolon on
xhr.setRequestHeader("Content-type", "application/json")
Thanks to #David Duponchel I used the jquery.binarytransport.js library, I sent the data to the API as JSON and got back the Zip File as Binary.
This is my JavaScript ZipDocs function:
self.zipDocs = function (docs, callback) {
$.ajax({
url: "../API/documents/zip",
type: "POST",
contentType: "application/json",
dataType: "binary",
data: docs,
processData: false,
success: function (blob) {
saveAs(blob, "ZippedDocuments.zip");
callback("Success");
},
error: function (data) {
callback("Error");
}
});
}
The API's code remains the same.
That works perfectly.

How to replicate jQuery ajax method

The problem: I'm trying to replicate the jQuery ajax method since I'm using XMLHttpRequest more than once in a script. However, I do not think including jQuery as a dependency is necessary since I would only be using a maximum of 3 methods from the jQuery library. Therefor I need a good way of replicating the jQuery's ajax method and so far I've gotten this far but please see explanation of output below the code example:
function ajax(obj) {
/*
obj = {
type: 'GET',
url: 'my/url/',
success: function (response) {},
error: function (response) {},
isTrue: true
}
*/
var
response = null, // defaults to null
complete = function (resp) {
console.log(resp); // outputs the response
response = resp;
},
error = function (resp) {
response = resp;
},
request = new XMLHttpRequest();
request.open(obj.type || 'GET', obj.url, obj.isTrue || true);
request.onreadystatechange = function (e) {
if (request.readyState === 4) {
if (request.status >= 200 && request.status < 400) {
complete(request.responseText);
} else {
error(request.statusText);
}
}
}
request.send();
return {
done: function (callback) {
callback(response);
}
}
}
Then when I call the ajax function in another function:
var xhr = ajax({
url: 'js/routes.js',
}).done(function (resp) {
console.log(resp); // outputs 'null'
});
the response variable is null although the complete() function set the response variable to the value of the ajax .responseText.
Question: How can I return the value of .responseText from the request to the object the ajax function is returning so that I can do something with it in a callback function like I intend to do inside the .done() method of that object?
Thank you!
You have an error in your implementation. The 'done' function does not wait for response.
function ajax(obj) {
/*
obj = {
type: 'GET',
url: 'my/url/',
success: function (response) {},
error: function (response) {},
isTrue: true
}
*/
var _callback = null,
response = null, // defaults to null
complete = function (resp) {
if(_callback){
_callback(resp);
}
response = resp;
},
error = function (resp) {
if(_callback){
_callback(resp);
}
response = resp;
},
request = new XMLHttpRequest();
request.open(obj.type || 'GET', obj.url, obj.isTrue || true);
request.onreadystatechange = function (e) {
if (request.readyState === 4) {
if (request.status >= 200 && request.status < 400) {
complete(request.responseText);
} else {
error(request.statusText);
}
}
}
request.send();
return {
done: function (callback) {
if(response){
callback(response);
}else{
_callback = callback;
}
}
}
}
EDIT*
consider using a microlibrary instead of jQuery. Don't reinvent the wheel.
http://microjs.com/#ajax

Categories

Resources