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
Related
This is a very simple callback function but I still can’t wrap my mind around it. Can someone try to explain it to me?
const getToDos = (one) => {
const req = new XMLHttpRequest();
req.addEventListener(`readystatechange`, () => {
if (req.readyState === 4 && req.status === 200) {
one(undefined, req.responseText);
}
else if (req.readyState === 4) {
one(`couldnt fetch data`, undefined);
}
});
req.open(`GET`, `https://jsonplaceholder.typicode.com/todos/`);
req.send();
};
getToDos((err, data) => {
if (err) {
console.log(err);
}
else {
console.log(data);
}
});
Also, can someone tell me what the difference is between XMLHttpRequest and the GET method? Are XMLHttpRequests used in the front end and GET methods used in the back end?
//Defining getToDos function, it takes one argument, which is another function
const getToDos = (one) => {
//Create a request
const req = new XMLHttpRequest();
//Add an event listener on the status of the request and gives code to execute when it happens
req.addEventListener(`readystatechange`, () => {
//if request is completed (4) and its status is good (200)
if (req.readyState === 4 && req.status === 200) {
//Call the callback function give undefined as error and req.responseText as data
one(undefined, req.responseText);
//if request is completed (4) and its status is good (!= 200)
} else if (req.readyState === 4) {
//Call the callback function give `couldnt fetch data` as error and undefined as data
one(`couldnt fetch data`, undefined);
}
});
//prepare request and give endpoint
req.open(`GET`, `https://jsonplaceholder.typicode.com/todos/`);
//send request
req.send();
};
//execute getToDos function and give a function as parameter
getToDos((err, data) => {
//if err is not undefined
if (err) {
//log error
console.log(err);
} else {
//log data
console.log(data);
}
});
This kind of code is old. Instead you should :
let data = await fetch(`https://jsonplaceholder.typicode.com/todos/`, {
method: 'GET',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json',
},
})
if(data.status == 200){
let parsed = await data.json()
console.log(parsed)
} else {
console.log(data)
}
–––––
Edit: Added example for the OP
const aFunction = (callback) => {
const aRandomBoolean = Math.random() < 0.5
if(aRandomBoolean){
console.log('Boolean is true !')
callback('first parameter', 'second parameter')
} else {
console.log('Boolean is false !')
callback('parameter 1', 'parameter 2')
}
}
aFunction((paramA, paramB)=>{
console.log(paramA, paramB)
})
I have created one XMLHttpRequest class wrapper for GET request. I am not able to console log the response i am getting. Is there something i am missing in the code ?
HttpWrapper.js
class HttpCall {
static get(endpoint, headers = {}) {
return new Promise((resolve, reject) => {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
//the request had been sent, the server had finished returning the response and the browser had finished downloading the response content
if (4 === xhr.readyState) {
if (200 <= xhr.status && 300 > xhr.status) {
resolve(xhr.response);
} else {
reject(xhr.status);
}
}
};
if (headers) {
Object.keys(headers).forEach(function (header) {
xhr.setRequestHeader(header, headers[header]);
});
}
xhr.open("GET", endpoint, true);
xhr.send(null);
});
}
}
export default HttpCall;
index.js
import HttpCall from "./utils/HttpWrapper";
import { BASE_BACKEND_URL } from "./constants/Config";
HttpCall.get(
BASE_BACKEND_URL + "?event_family=session&source_id=guru1",
function (response) {
console.log(response);
}
);
It looks like you're passing a callback to your method call instead of using the promise you returned. Your call should be formed more like:
HttpCall.get(
BASE_BACKEND_URL + "?event_family=session&source_id=guru1")
.then((response) => {
// handle resolve
console.log(response);
}).catch((error) => {
// handle reject
console.error(error);
})
How to check XMLHttpRequest While I'm getting status as 200 why it's not checking my xhr
angular.module("productManagement").controller('Employee', function ($scope, EmployeeService) {
var xhr = new XMLHttpRequest();
$scope.GetdataBySubmit = function () {
var GetData = EmployeeService.GetEmployeeData();
debugger;
GetData.then(function(d) {
if (xhr.status == "200") {
$scope.Employee = d.data;
$('#TadleData').show();
} else {
console.log("")
}
})
}
})
Here I'm Updating My GetEmployeeData Code
angular.module("productManagement").service("EmployeeService", function
($http) {
this.GetEmployeeData = function () {
var x=$http({
url: "http://localhost:9632/Api/Employee",
method:"Get",
data:JSON.stringify()
})
return x;
}
})
No need to define and use xhr variable
As you are using $http and returning Promise, Use the success callback handler response object.
GetData.then(function (response) {
if (response.status == 200) {
$scope.Employee = response.data;
$('#TadleData').show();
}
}, function (response) {
console.log("Do something on error")
})
I've read through several posts related this this kind of issue, but I'm still not identifying the issue here.
When the following function is called and receives a 200 response, all is well; when it encounters 404 the ajax is repeated; adding a timeout only limits the time frame during which the repeat requests are made. There has to be a simple reason for this, but it is eluding me ...
function myFunction(ID) {
var url = 'http://example.org/' + ID;
var response;
$.ajax(url, {
success: function (responseText) {
if (responseText !== undefined) {
response = responseText;
}
},
error: function (xhr, ajaxOptions, errorMsg) {
if (xhr.status == 404) {
console.log('404: ' + errorMsg);
} else if (xhr.status == 401) {
console.log('401: ' + errorMsg);
}
}
});
return response;
}
You can use the below given approach to get the data for your error without repetition in AJAX.
$.ajax(url, {
success: function (responseText) {
if (responseText !== undefined) {
response = responseText;
}
},
error: function (xhr) {
//the status is in xhr.status;
//the message if any is in xhr.statusText;
}
});
UPDATE
You cannot return the response because you have an async request and response variable will be returned before the actual ajax requests gives a response. So I suggest You either use a callback function on success ore use a synchronous request.
So to get the response you can have a function like so:
function getResponse() {
return $.ajax({
type: "GET",
url: your_url,
async: false
}).responseText;
}
Or the callback approach is:
$.ajax(url, {
success: function (responseText) {
if (responseText !== undefined) {
theCallbackFunction(responseText);
}
},
error: function (xhr) {
//the status is in xhr.status;
//the message if any is in xhr.statusText;
}
});
function theCallbackFunction(data)
{
//do processing with the ajax response
}
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;
}
}