I am trying to create a draft in gmail using google api.
After authorization I am having trouble using POST to send request body. Here is a simplified version of my code.
var token = hash[1].split('=')[1]; // getting token
var body = "some text";
var base64message = Base64.encode(body); //uses base64 library to encode message
var params ={
"message": {
"raw": base64message
}
}
var request = new XMLHttpRequest();
request.onload = function(){
console.log(this.responseText); // parseError
}
request.open('POST','https://www.googleapis.com/gmail/v1/users/me/drafts?access_token='+token,true);
request.send(JSON.stringify(params));
Solved forgot this:
request.setRequestHeader('Content-Type', 'application/json');
Instead of:
request.onload = function(){
console.log(this.responseText); // parseError
}
Use onreadystatechange after which you ask if(this.readyState == 4 && this.status == 200){.
this.readyState == 4 means that the request is finished or processed
this.status == 200 means that it also succeeded.
.onload was added in XMLHttpRequest 2 whereas onreadystatechange has been around since the original spec. .onload is equal only to this.readyState == 4.
So your code will look like this:
var token = hash[1].split('=')[1]; // getting token
var body = "some text";
var base64message = Base64.encode(body); //uses base64 library to encode message
var params ={
"message": {
"raw": base64message
}
};
var request = new XMLHttpRequest();
request.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(this.responseText);
}
};
request.open('POST','https://www.googleapis.com/gmail/v1/users/me/drafts?access_token='+token,true);
request.send(JSON.stringify(params));
Related
Hope you are able to help or just help me understand why I have 2 almost similar codeblocks where one does not do what I expect.
I am trying to make some API calls where I populate a variable with the data that is pulled from the API call. In the first there is no problem at all, but the second I can't populate the variable.
I have tried googling the problem and it seems to be because of the asynchronous nature of XmlHttprequests. But again, I do not get why one solutions works and another don't.
The solution that work:
// Get JSON and convert it to an object
var obj;
const Http = new XMLHttpRequest();
const url = "https://type.fit/api/quotes";
Http.open("GET", url);
Http.send();
Http.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
obj = JSON.parse(Http.responseText);
}
};
In this solution I am able to get the data and populate the variable obj and use it globally.
link to the solution: https://codepen.io/Kfriis/pen/QWjGZmx
The solution that don't work:
//function that takes a currency in capital letters and returns
var rates;
var currency = 'gbp';
const currencyString = currency.toUpperCase();
const API = "api.frankfurter.app"
const URL = `https://${API}/latest?amount=1&from=${currencyString}&to=DKK`
const http = new XMLHttpRequest();
http.open("GET", URL);
http.send();
http.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
rates = JSON.parse(http.responseText);
}
};
console.log(rates)
This do, for some reason, not work. I do not get why the rates variable do not get populated since the request is basically the same for the first code snippet.
I have come down to an idea of it being because the data sent from the 2 API endpoints may be different in some way. Because if it was only because of the asynchronous requests, both code snippets should return undefined.
Link https://codepen.io/Kfriis/pen/VwvpKmd
I do hope someone is able to shine some light on this.
I must be doing something wrong in the second snippet, because I can console.log() from inside the onreadystatechange but not outside it. Which led me to believe for a long time that it was a scoping issue.
Your code does work. However, you're logging console.log(rates) outside the http.onreadystatechange-function which means you're logging the rates before you get the response. If you change the code block
http.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
rates = JSON.parse(http.responseText);
}
};
console.log(rates)
to
http.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
rates = JSON.parse(http.responseText);
console.log(rates)
}
};
it should work.
Here's a working example code if you wanna add the code to a function.
// Function that takes a currency in capital letters and returns
function getCurrencyRates(currency, cb) {
const currencyString = currency.toUpperCase();
const API = "api.frankfurter.app"
const URL = `https://${API}/latest?amount=1&from=${currencyString}&to=DKK`
const http = new XMLHttpRequest();
http.open("GET", URL);
http.send();
http.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
cb(JSON.parse(http.responseText));
}
};
}
// Call the function and pass "gbp" as currency.
// Rates will be logged in response.
getCurrencyRates('gbp', function(response) {
console.log(response);
});
I'm trying to send a post request to linkedin services from my backend.
exports.GetAccessToken = function (req, res) {
var xhttp = new XMLHttpRequest();
var decoded = jwt.verify(req.query.jwt_token, MariaDB_config.PUB_key);
xhttp.onreadystatechange = function () { // handle request response
if (this.readyState === 4 && this.status === 200) {
console.log("answer : " + this.responseText);
}
};
xhttp.handleError()
// Send a post request
xhttp.open("POST", "https://www.linkedin.com/oauth/v2/accessToken?code=" + decoded.code + "privatestuff", true);
xhttp.send();
}
And I get below error :
TypeError: Cannot read property 'stack' of undefined
This method was working fine until now.
I was using "xhttp.handleError()" wrong, I deleted it and now it works fine.
I'm trying to inject new user into a separate database after they sign up on Auth0. I was told that using hook is sufficient but I'm not sure how to make the call.
I tried
var django_endpoint = 'some/endpoint/';
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
alert(this.responseText);
}
};
xhttp.open("POST", django_endpoint, true);
xhttp.setRequestHeader("Content-type", "application/json");
xhttp.send('{"username": user.email}');
cb(null, user, context);
and ran it, but my endpoint is not receiving anything although the result shows 200 on the auth0 test screen
I am new to AJAX and I am trying to make a call to my json file but it is not returning anything in console. I looked into network tab, the xhr status is 200.
const xhr = new XMLHttpRequest();
xhr.readyState = function(){
if(xhr.readyState === 4){
console.log(xhr.responseText)
}
}
xhr.open('GET','data/task.json');
xhr.send();
and task.json is
{
"jobs": [
{
"id": 7,
"title": "Clerk",
"employer": {
"name": "AOL"
},
"location": "Floria",
"salary": "$45k+"
}
]
}
I tried parsing it and using console to print it out but the console is empty as well.
There a few things to notice in the request that you are making.
You need to add the status to 200 because it's the OK status. Meaning that your request go through. So that part will exactly become (this.readyState == 4 && this.status == 200).
You also need to change from using triple equal signs === to == because you are not comparing by TYPE as a triple equals is used in JS.
Using the event handler xhttp.onreadystatechange instead of xmr.readySate. Here is a link to the Mozilla documentation.
So it should become:
const xhttp = new XMLHttpRequest();
xhttp.onreadystatechange= function(){
if(xhttp.readyState === 4 && xhttp.status == 200){
console.log(xhr.responseText)
}
}
xhr.open('GET','data/task.json');
xhr.send();
Here is a detailed documentation from W3Schools Documentation with example.
You need onreadystatechange not readyState
const xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
console.log(xhr.responseText)
}
}
xhr.open('GET','data/task.json');
xhr.send();
Instead of xhr.readyState you should use xhr.onreadystatechange
like that:
xhr.onreadystatechange = function(){
if(xhr.readyState === 4){
console.log(xhr.responseText)
}
}
I have a textarea where users can enter multiple URLs which in return will be used for an API request.
The issue I run into is that only the last URLs API request gets captured (sometimes multiple times).
$('.start').on('click',function()
{
var url_list = $("#url-list").val();
var urls = url_list.split("\n");
for (var i = 0, len = urls.length; i < len; i++) {
console.log("i is "+i)
var xhr = new XMLHttpRequest();
xhr.open('GET', urls[i], true);
xhr.send();
xhr.onreadystatechange = processRequest;
// send API request
function processRequest() {
if (xhr.readyState == 4 && xhr.status == 200) {
var response = JSON.parse(xhr.responseText);
console.log(response);
}
}
}
});
I don't see exactly where I am doing something wrong, I might be blind to it or just don't know any better. Any help would be appreciated. PS. fairly new to making API requests.
Welcome to closures.
The problems here are:
The loop could be finished before the first request starts, so it takes the last url in the array
In the callback you are referencing the same xhr object
You can try one of the different solutions here.
Replacing xhr with this in the callback is the fastest fix:
function processRequest() {
if (this.readyState == 4 && this.status == 200) {
var response = JSON.parse(this.responseText);
console.log(response);
}
}
See this fiddle for a running example.
You could update your code like this
var requestIndex = 0;
var urls = [];
$('.start').on('click',function()
{
// Reset request index
requestIndex = 0;
var url_list = $("#url-list").val();
urls = url_list.split("\n");
// Send Http request
sendRequest(urls, requestIndex);
});
// Send Http request
function sendRequest(urls, index) {
// Send API request
var xhr = new XMLHttpRequest();
xhr.open('GET', urls[index], true);
xhr.onreadystatechange = processRequest;
xhr.send();
}
// Process API request
function processRequest(e) {
if (e.target.readyState == 4 && e.target.status == 200) {
var response = JSON.parse(e.target.responseText);
console.log(response);
}
requestIndex++;
if (requestIndex < urls.length) {
sendRequest(urls, requestIndex);
}
}