Status Code 304 - javascript

I am new to Javascript and server-side programming. I am trying to send a GET request to load an image from my blog: http://jsafaiyeh.github.io/img/suw_background.png
function imgLoad(url) {
return new Promise(function(resolve, reject) {
var request = new XMLHttpRequest({mozSystem: true});
request.open('GET', url);
request.responseType='blob';
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
resolve(request.response);
} else {
reject(Error('Image did\'t load successfully; error code '+ request.statusText));
}
};
request.onerror= function() {
reject(Error('There was a network Error'));
};
request.send();
});
}
var body = document.querySelector('body');
var myImage = new Image();
imgLoad('http://jsafaiyeh.github.io/img/suw_background.png').then(function response() {
var imageURL = window.URL.createObjectURL(response);
myImage.src = imageURL;
body.appendChild(myImage);
}, function(Error) {
console.log(Error);
});
I get status code 304. However, the image still does not load onto the page. Any help would be appreciated.

You have wrong function signature. It should be like this:
imgLoad('http://jsafaiyeh.github.io/img/suw_background.png').then(function (response) {
var imageURL = window.URL.createObjectURL(response);
myImage.src = imageURL;
body.appendChild(myImage);
}, function(Error) {
console.log(Error);
});
Working demo on JSFiddle(at least in Chrome).
Instead of passing named function, called response you probably wanted response to be in argument list. So, instead of function response(), you need function (response). You didn't get error that response was undefined, because it actually was declared, but it wasn't expected result from promise, but function.

Related

Chaining promises - correct methodology

I'm trying to create an excel add-in using Javascript that requires asynchronous functions return a JS promise to Excel and that the promise is resolved with the final value using the callback function. I am new to promises and have spent hours reading and testing this out with no success, and was hoping someone could help me understand what I'm doing wrong. Below is the code:
function TEST(num1) {
return new Promise(function (resolve) {
var corsproxy = "https://cors-anywhere.herokuapp.com/"
var apiurl = "https://randomapi.com/testapi"
var data = getData(corsproxy+apiurl).then(function(result){
console.log ("here it comes")
console.log(result.meta.status) /// This returns "Success"
return (result.meta.status) /// I need this to be resolved
})
console.log("last")
resolve(data)
})
};
/// Get JSON
function getData(url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'json';
xhr.onload = function () {
try {
if (xhr.status === 200) {
resolve(xhr.response);
}
else if (xhr.status !== 200) {
reject({
error: 'Request failed. ' + xhr.response
});
}
} catch (e) {
reject({
error: e
});
}
};
xhr.send();
});
}
The second function getData is working as intended and returning a JS Object. What I'm trying to accomplish with the TEST function is:
Create a new promise - this needs to be resolved/returned as "Success"
Call the API data with getData(temporarily running through a proxy to bypass CORS erros)
Extract the meta.status value ("Success")
I've tried a number of different things but the current code write "last" and resolves an undefined data before the getData function completes. Changing the "return (result.meta.status)" to "resolve (result.meta.status)" also doesn't help.
Any assistance with what I'm doing wrong would be greatly appreciated.
function TEST(num1) {
var corsproxy = "https://cors-anywhere.herokuapp.com/"
var apiurl = "https://randomapi.com/testapi"
return getData(corsproxy+apiurl)
}
TEST(valofnum1).then(function(result){
console.log ("here it comes")
console.log(result.meta.status) /// This returns "Success"
return (result.meta.status) /// Needs to be resolved
})
that's how you chain promises. you don't resolve a promise within another promise,
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises
You can use async/await since ES6 that solves a lot of this headache by simplifying the chain process into using await statements when letting promises resolve. I've updated your code block to use it, take a look:
async function TEST(num1) {
return new Promise(function (resolve) {
var corsproxy = "https://cors-anywhere.herokuapp.com/"
var apiurl = "https://randomapi.com/testapi"
var result = await getData(corsproxy+apiurl);
resolve(result.meta.status)
})
};
/// Get JSON
function getData(url) {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'json';
xhr.onload = function () {
try {
if (xhr.status === 200) {
resolve(xhr.response);
}
else if (xhr.status !== 200) {
reject({
error: 'Request failed. ' + xhr.response
});
}
} catch (e) {
reject({
error: e
});
}
};
xhr.send();
});
}
Changes made:
TESTis now an async function.
Rather chaining the resolved promise from getData and resolving in TEST, you simply await the response from getData and then resolve it.

AJAX POST request with response

As the title states, I'm looking to make a POST request using JavaScript and also get a response. Here's my current code:
var request = new XMLHttpRequest();
request.open('POST', 'test.php', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success
console.log(request.responseText)
} else {
// Server-side Error
console.log("Server-side Error")
}
};
request.onerror = function() {
// Connection Error
console.log("Connection Error")
};
request.send({
'color':'red',
'food': 'carrot',
'animal': 'crow'
});
With test.php being:
<?php
echo $_POST['color'];
?>
This should return 'red' but instead returns nothing.
This seems like a simple problem but I could only find solutions for people using jQuery. I'd like a solution that does not rely on and libraries.
The send method takes a string rather than an object, perhaps more like:
var request = new XMLHttpRequest();
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
console.log(request.response)
} else {
console.log("Server-side Error")
}
};
request.onerror = function() {
console.log("Connection Error")
};
request.open('POST', 'test.php', true);
request.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
request.send('color=red&food=carrot&animal=crow');
The JavaScript problem
You are trying to send a generic Object, so it gets converted to a String ("[Object object]"), and the data is lost.
Convert the data to a FormData object instead.
var data = {
'color':'red',
'food': 'carrot',
'animal': 'crow'
};
var formData = new FormData();
Object.keys(data).forEach(function (key) {
formData.append(key, data[key]);
})
request.send(formData);
The PHP problem
All of the current solutions simply log the source code of "test.php" to the console as opposed to logging 'red' to the console
This is an issue unrelated to your code. It is also a FAQ. See: PHP code is not being executed, instead code shows on the page

I don't understand Ajax, Promise and XMLHttpRequest

this is my code:
const getXHR = (type, url) => {
let xhr = new XMLHttpRequest();
let p = new Promise(function(resolve, reject) {
xhr.onload = function() {
if(xhr.status >= 200 && xhr.status < 400) {
resolve(xhr.responseText);
} else {
reject(new Error(`Error. Code ${xhr.status}`))
}
};
xhr.onerror = function() {
reject(new Error(`Error. Problem with connection`));
}
});
xhr.open(type, url);
return {xhr, p};
};
export default {
get(url) {
var _getXHR = getXHR('GET', url),
xhr = _getXHR.xhr,
p = _getXHR.p;
xhr.send();
return p;
}
}
I don't understand why I have to use this code to get it to work:
var _getXHR = getXHR('GET', url),
xhr = _getXHR.xhr,
p = _getXHR.p;
instead of this:
var xhr = getXHR('GET', url).xhr,
p = getXHR('GET', url).p;
What is wrong with this? For me it is excatly the same lines of code. I would be grateful for any kind of help. Maybe someone has a link where I can find the answer?
Thank You
var xhr = getXHR('GET', url).xhr,
p = getXHR('GET', url).p;
Creates two requests, and then gets the xhr object of the first, and the promise of the second. The xhr request of the first is sent , that one of the promise is always in a pending state. So thats probably not working. May use some destructuring:
var { p, xhr } = getXHR('GET', url);
xhr.send();
return p;

Overriding a variable within another function JS

Is it possible for me to call a function then override the contents of the variable before actually running it?
So I have a function that basically pulls in my Git profile like this:
var GetGitInfo = function() {
var xhr = new XMLHttpRequest();
var gitURL = "https://api.github.com/users/myself/repos";
xhr.open("GET", gitURL);
xhr.send(null);
xhr.onreadystatechange = function() {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
// console.log(xhr.responseText);
console.log(JSON.parse(xhr.responseText));
} else {
console.log('Error: ' + xhr.status);
}
}
};
}
Then I call the function in another step by doing GetGitInfo(); which all works fine.
However, If I wanted to call the function and replace the gitURL variable how would I achieve that?
So something like
GetGitInfo(
gotURL= "https://api.github.com/users/new_user/repo";
);
You can't modify a local variable to a function from outside the function. They are private to the function's implementation.
But, since it's your own function, you can just create an argument that can be passed into the function. You can even make the argument optional so it will take your initial value as the default value if it is not passed.
var GetGitInfo = function(url) {
var xhr = new XMLHttpRequest();
var gitURL = url || "https://api.github.com/users/myself/repos";
xhr.open("GET", gitURL);
xhr.send(null);
xhr.onreadystatechange = function() {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
// console.log(xhr.responseText);
console.log(JSON.parse(xhr.responseText));
} else {
console.log('Error: ' + xhr.status);
}
}
};
}
Then, you can use the function the way you were using it or you can pass in an URL to use:
getGitInfo(); // uses your default URL
getGitInfo("http://someURL"); // uses the URL you pass in
FYI, this function looks like it will ultimately need to either return a promise or accept a callback so you can communicate the results back to the caller.
From the snippet above you need to set the url as a function parameter so when calling it uses the specified url.
var GetInfo = function(url) {
var xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.send(null);
xhr.onreadystatechange = function() {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
// console.log(xhr.responseText);
console.log(JSON.parse(xhr.responseText));
} else {
console.log('Error: ' + xhr.status);
}
}
};
GetInfo("https://api.github.com/users/myself/repos");
You should do a toString() on the function:
GetGitInfo.toString()
Then you should do a text search and replace on the variable and it's data:
GetGitInfo.toString().substring(0,GetGitInfo.indexOf('somestring'))+'gitUrl="newURL"'+GetGitInfo.toString().substring(.......)
Then you should eval that string!
Or, you know, use function parameters. Either way. Whatever's easiest.
Pass a parameter to the function:
var GetGitInfo = function(gitURL) {
var xhr = new XMLHttpRequest();
xhr.open("GET", gitURL);
xhr.send(null);
xhr.onreadystatechange = function() {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
// console.log(xhr.responseText);
console.log(JSON.parse(xhr.responseText));
} else {
console.log('Error: ' + xhr.status);
}
}
};
}
GetGetInfo("https://api.github.com/users/myself/repos");
Just add a parameter to your function:
var GetGitInfo = function(gitURL) {
var xhr = new XMLHttpRequest();
xhr.open("GET", gitURL);
xhr.send(null);
xhr.onreadystatechange = function() {
var DONE = 4; // readyState 4 means the request is done.
var OK = 200; // status 200 is a successful return.
if (xhr.readyState === DONE) {
if (xhr.status === OK) {
// console.log(xhr.responseText);
console.log(JSON.parse(xhr.responseText));
} else {
console.log('Error: ' + xhr.status);
}
}
};
}
and call it like this:
GetGitInfo("https://api.github.com/users/myself/repos");
Use the parameters
var getData = function(url){
// url can be used here
}
var data = getData("http://apiurl.xy")

What is the vanilla JS version of Jquery's $.getJSON

I need to build a project to get into a JS bootcamp I am applying for. They tell me I may only use vanilla JS, specifically that frameworks and Jquery are not permitted. Up to this point when I wanted to retrieve a JSON file from an api I would say
$.getJSON(url, functionToPassJsonFileTo)
for JSON calls and
$.getJSON(url + "&callback?", functionToPassJsonPFileTo)
for JSONP calls. I just started programming this month so please bear in mind I don't know the difference between JSON or JSONP or how they relate to this thing called ajax. Please explain how I would get what the 2 lines above achieve in Vanilla Javascript. Thank you.
So to clarify,
function jsonp(uri){
return new Promise(function(resolve, reject){
var id = '_' + Math.round(10000 * Math.random())
var callbackName = 'jsonp_callback_' + id
window[callbackName] = function(data){
delete window[callbackName]
var ele = document.getElementById(id)
ele.parentNode.removeChild(ele)
resolve(data)
}
var src = uri + '&callback=' + callbackName
var script = document.createElement('script')
script.src = src
script.id = id
script.addEventListener('error', reject)
(document.getElementsByTagName('head')[0] || document.body || document.documentElement).appendChild(script)
})
}
would be the JSONP equivalent?
Here is the Vanilla JS version for $.getJSON :
var request = new XMLHttpRequest();
request.open('GET', '/my/url', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
// Success!
var data = JSON.parse(request.responseText);
} else {
// We reached our target server, but it returned an error
}
};
request.onerror = function() {
// There was a connection error of some sort
};
request.send();
Ref: http://youmightnotneedjquery.com/
For JSONP SO already has the answer here
With $.getJSON you can load JSON-encoded data from the server using
a GET HTTP request.
ES6 has Fetch API which provides a global fetch() method that provides an easy, logical way to fetch resources asynchronously across the network.
It is easier than XMLHttpRequest.
fetch(url) // Call the fetch function passing the url of the API as a parameter
.then(res => res.json())
.then(function (res) {
console.log(res)
// Your code for handling the data you get from the API
})
.catch(function() {
// This is where you run code if the server returns any errors
});
Here is a vanilla JS version of Ajax
var $ajax = (function(){
var that = {};
that.send = function(url, options) {
var on_success = options.onSuccess || function(){},
on_error = options.onError || function(){},
on_timeout = options.onTimeout || function(){},
timeout = options.timeout || 10000; // ms
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
//console.log('responseText:' + xmlhttp.responseText);
try {
var data = JSON.parse(xmlhttp.responseText);
} catch(err) {
console.log(err.message + " in " + xmlhttp.responseText);
return;
}
on_success(data);
}else{
if(xmlhttp.readyState == 4){
on_error();
}
}
};
xmlhttp.timeout = timeout;
xmlhttp.ontimeout = function () {
on_timeout();
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
return that;
})();
Example:
$ajax.send("someUrl.com", {
onSuccess: function(data){
console.log("success",data);
},
onError: function(){
console.log("Error");
},
onTimeout: function(){
console.log("Timeout");
},
timeout: 10000
});
I appreciate the vanilla js equivalent of a $.getJSON above
but I come to exactly the same point. I actually was trying of getting rid of jquery which I do not master in any way .
What I'm finally strugglin with in BOTH cases is the async nature of the JSON request.
What I'm trying to achieve is to extract a variable from the async call
function shorten(url){
var request = new XMLHttpRequest();
bitly="http://api.bitly.com/v3/shorten?&apiKey=mykey&login=mylogin&longURL=";
request.open('GET', bitly+url, true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
var data = JSON.parse(request.responseText).data.url;
alert ("1:"+data); //alerts fine from within
// return data is helpless
}
};
request.onerror = function() {
// There was a connection error of some sort
return url;
};
request.send();
}
now that the function is defined & works a treat
shorten("anyvalidURL"); // alerts fine from within "1: [bit.ly url]"
but how do I assign the data value (from async call) to be able to use it in my javascript after the function was called
like e.g
document.write("My tiny is : "+data);

Categories

Resources