How to handle XMLHttpRequests in a redux action? - javascript

I have a redux-form that is passing props to my action. The property this.props.userImages[0] is an image file from a file input on that form. I'm then taking that image and making and XMLHttpRequest to Cloudinary which generates a url for that image. Once I receive the url data (xhr.responseText), I'd like to then merge it with my other props to that I can then post all of my props to an API (all form info + newly created image URL).
I know that I have to wait for my request to generate a url to resolve, but having issues with getting it right before I can pass it onto my other function which can take that info and merge it in with props before posting to my API.
//..
function generateUrl(props) {
// Grabs image file from my form's file input and uploads
// to cloudinary service so that a URL can be generated
const cloudinaryURL = 'https://api.cloudinary.com/v1_1/<my_name>/image/upload';
const apiKey = 'secret_key';
const uploadPreset = 'test_preset';
const data = new FormData();
data.append('file', props.userImages[0]);
data.append('upload_preset', uploadPreset);
data.append('api_key', apiKey);
const xhr = new XMLHttpRequest();
xhr.open('POST', cloudinaryURL, true);
xhr.send(data);
xhr.onReadyStateChange = () => {
if (xhr.readyState == 4 && xhr.status == 200) {
return JSON.parse(xhr.responseText);
}
};
return xhr.onReadyStateChange();
}
export function createReview(props) {
const imageUrl = generateUrl(props);
const mergedProps = //...
// Here I'd like to merge my newly generated
// url back into props before I post to my API like so...
const request = axios.post(`${REQUEST_URL}/api`, mergedProps)
return {
type: CREATE_REVIEW,
payload: request
}
};
Any and all help is greatly appreciated.

This has nothing to do with promises in the context of your example XMLHttpRequest based code.
The assumption your making is that the callback assigned to onReadyStateChange does something with it's return value. Instead anything returned from that function is dutifully ignored.
What you want is to pass the value onward through another callback.
function generateUrl(props, callback) {
// Do things here
xhr.onReadyStateChange = () => {
if (xhr.readyState == 4 && xhr.status == 200) {
callback(JSON.parse(xhr.responseText));
}
};
}
generateUrl(props, (response) => {
const mergedProps = // Use response as expected.
});
Since you mentioned promise and your using ES2015 we can convert this to actually use promises which is probably what you wanted to begin with.
function generateUrl(props) {
return new Promise((resolve, reject) => {
const cloudinaryURL = 'https://api.cloudinary.com/v1_1/<my_name>/image/upload';
const apiKey = 'secret_key';
const uploadPreset = 'test_preset';
const data = new FormData();
data.append('file', props.userImages[0]);
data.append('upload_preset', uploadPreset);
data.append('api_key', apiKey);
const xhr = new XMLHttpRequest();
xhr.onReadyStateChange = () => {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
resolve(xhr.responseText);
} else {
reject(new Error(`Failed HTTP request (${xhr.status})`));
}
};
xhr.onerror = reject;
xhr.open('POST', cloudinaryURL, true);
xhr.send(data);
});
}
generateUrl(props)
.then(JSON.parse)
.then(results => {
// Do something with response
})
.catch(error => {
// Do something with the error
});

Related

XMLHttpRequest return from a function before response is back

I have a function as the code below, I am trying to send a file through XMLHttpRequest to the server and then store it in DB and retrieve the id of the file in DB and make an object of ids.
The problem is that the function exits a lot before I got the response back from the server to store it in the object therefore the object doesn't store those values.
I know that I need make the XHR asynchronous but it doesn't change the result, I have also tried timeout or using a different platform like Ajax but still, it didn't work.
async function getFileObj() {
var FileObject = {}
for (let key1 in PObj) {
FileObject[key1] = {}
for (let key2 in PObj[key1]) {
FileObject[key1][key2] = {}
for (let key3 in PObj[key1][key2]) {
const formData = new FormData();
formData.append('myFile.png', filesObjDB[key1][key2][key3]);
var xhr = new XMLHttpRequest();
xhr.open("POST", 'url', true);
xhr.onreadystatechange = async function() {
if (this.readyState === XMLHttpRequest.DONE && this.status === 200)
var id = await xhr.response.text();
FileObject[key1][key2][key3] = parseInt(id)
}
xhr.responseType = 'blob';
xhr.send(formData);
}
}
}
return FileObject;
}
Help would be very appreciated!
You are not awaiting the request. To make the existing code wait for the result, you'd need to wrap the outdated callback-based code in a promise and await that (and also I don't think getting the response text of an XHR works as you showed, I changed it now):
// This is just to demonstrate what was immediately wrong
// with the existing code - it's not the best solution! See below.
FileObject[key1][key2][key3] = await new Promise((resolve, reject) => {
var xhr = new XMLHttpRequest();
xhr.open("POST", url, true);
xhr.onreadystatechange = function() {
if (this.readyState === XMLHttpRequest.DONE && this.status === 200) {
var id = xhr.responseText;
resolve(parseInt(id));
}
};
xhr.send(formData);
});
Note there is no error handling yet, if the request fails everything will just hang.
But at that point, it doesn't actually make sense to use XHR in the first place! It's a lot more straightforward to use fetch, which has a promise API out of the box:
const response = await fetch(url, { method: 'POST', body: formData })
FileObject[key1][key2][key3] = parseInt(await response.text())

Javascript XMLHTTPRequest .classList in response

How can I check if the response received from XMLHTTPRequest has a particular class or not?
async function swipeAction(currentElementObj) {
var cardId = currentElementObj.getAttribute("value");
var dataString = {'card': cardId};
let response = await new Promise(resolve => {
var xhr = new XMLHttpRequest();
xhr.open("POST", "processes/explore.php", true);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.send(JSON.stringify(dataString));
xhr.onreadystatechange = function() {
if(xhr.readyState == 4 && xhr.status == 200) {
// I WANT TO CHECK SOMETHING LIKE THIS
if(xhr.response.getElementById("matched").classList.contains('matched'))
alert(xhr.response.getElementById("matched").classList);
}
}
});
}
In the response received, I want to check if the element with id matched has a class name matched or not. However, the above code isn't working. What should be the proper approach here?
If you're expecting plain text/html response from the server then processing it may look like that:
async function swipeAction(currentElementObj) {
var cardId = currentElementObj.getAttribute("value");
var dataString = { card: cardId };
let response = await new Promise((resolve, reject) => {
try {
var xhr = new XMLHttpRequest();
xhr.open("POST", "processes/explore.php", true);
xhr.setRequestHeader("Content-Type", "application/json");
// add responseType = "document" for response to be parsed into DOM
xhr.responseType = "document";
// override response mime type (in case your server sends text/plain)
xhr.overrideMimeType("text/html");
xhr.send(JSON.stringify(dataString));
xhr.onreadystatechange = function () {
// check for non-empty responseXML property
if (xhr.readyState == 4 && xhr.status == 200 && xhr.responseXML) {
const matched = xhr.responseXML.getElementById("matched");
if (!matched) return reject("Element not found in response");
if (matched) {
alert(matched.classList.contains("matched"));
resolve(true);
}
} else {
return reject("Incompatible response format");
}
};
} catch (e) {
reject(e.toString());
}
});
}

Display Javascript Ajax webservice request

I was trying to display an ajax request from a web service in my HTML.
I can display the result in the console but can not retrieve the result and then display it in my HTML.
I want to display the result of the request in "weather-result" div by clicking the "ask-weather" button.
Her is my code.
Thank everyone.
const askWeather = function(result){
var request = new XMLHttpRequest();
request.onreadystatechange = function subFunction() {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
result = JSON.parse(this.responseText);
return result.current_condition.condition;
}
};
request.open("GET", "https://www.prevision-meteo.ch/services/json/paris");
request.send();
}
const ask = document.getElementById('ask-weather');
ask.addEventListener('click', function(){
const weatherResult = document.getElementById('weather-result');
weatherResult.innerHTML = askWeather();
});
<html>
<head>
<link rel="stylesheet" type="text/css" href="base.css">
</head>
<body>
<div><button id="ask-weather">Quelle est la météo sur Paris ?</button></div>
<div id="weather-result"></div>
<script type="text/javascript" src="index.js"></script>
</body>
</html>
This seems like a asynchronous/callback problem here. When the button is clicked, it sends a request somewhere and will return right away (with undefined in case of the code above - this can be checked by saving it in a variable and console.log it).
When askWeather() is called, it could return something itself. The return in request.onreadystatechange cannot return for askWeather as it's happening multiple times and later - after askWeather is done and the request is being sent.
If you pass a function a variable and set it to something new in its body, it will not be changed for the caller. That means doing result = ... does not really help, if you wanted to pass a variabel and get it set by the inner function.
A different approach is necessary to handle this. Here are a few alternatives:
To keep it as most similar to the code you had, you can set the innerHTML in the onreadystatechange function:
const askWeather = function() {
var request = new XMLHttpRequest();
request.onreadystatechange = function subFunction() {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
const result = JSON.parse(this.responseText);
// set it here directly
const weatherResult = document.getElementById('weather-result');
weatherResult.innerHTML = result.current_condition.condition;
}
};
request.open("GET", "https://www.prevision-meteo.ch/services/json/paris");
request.send();
}
const ask = document.getElementById('ask-weather');
ask.addEventListener('click', function() {
askWeather();
});
Make it more general and let askWeather use a callback (call a function when it's "done"):
const askWeather = function(callback) {
var request = new XMLHttpRequest();
request.onreadystatechange = function subFunction() {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
const result = JSON.parse(this.responseText);
// send the result to the passed "callback" function
callback(result.current_condition.condition);
}
};
request.open("GET", "https://www.prevision-meteo.ch/services/json/paris");
request.send();
}
const ask = document.getElementById('ask-weather');
ask.addEventListener('click', function() {
askWeather(function (result) { // this whole function is the "callback" parameter
const weatherResult = document.getElementById('weather-result');
weatherResult.innerHTML = result;
});
});
(a) Let askWeather return a promise and use it in the caller
const askWeather = () => new Promise((resolve, reject) => {
var request = new XMLHttpRequest();
request.onreadystatechange = function subFunction() {
if (this.readyState == XMLHttpRequest.DONE && this.status == 200) {
const result = JSON.parse(this.responseText);
// send the result to the passed "callback" function
resolve(result.current_condition.condition);
}
// not sure about the error path here, but something like this:
if (this.readyState == XMLHttpRequest.DONE && this.status != 200) {
reject(new Error("There was an error with the XMLHttpRequest!"));
}
};
request.open("GET", "https://www.prevision-meteo.ch/services/json/paris");
request.send();
});
const ask = document.getElementById('ask-weather');
ask.addEventListener('click', function() {
askWeather()
.catch((err) => weatherResult.innerHTML = err.message) // to handle possible errors, maybe?
.then((result) => { // like the callback solution, but as promise!
const weatherResult = document.getElementById('weather-result');
weatherResult.innerHTML = result;
});
});
});
(b) Additionally to the Promise solution, in newer browsers there is already async and await syntax:
ask.addEventListener('click', async function() {
try {
const result = await askWeather(); // this "pauses" until the Promise return of `askWeather` resolves (or throws an error if it doesn't)
const weatherResult = document.getElementById('weather-result');
weatherResult.innerHTML = result;
} catch (e) {
// error could be handled here
}
});
Instead of XMLHttpRequest, use the fetch API, which usually should be available if Promises are available in the browsers you support. The solution is in the comments of the original question. With most modern browsers, this should work:
ask.addEventListener('click', async () => {
const response = await fetch("https://www.prevision-meteo.ch/services/json/paris");
const result = await response.json();
const weatherResult = document.getElementById('ask-weather');
weatherResult.innerHTML = result.current_condition.condition;
});
If you don't have to support IE, I would use the fetch alternative.
I hope the other alternatives make it clear, asynchronous patterns can be resolved in JavaScript.
function getJSON(path) {
return new Promise(function(resolve, reject) {
var xhttp = new XMLHttpRequest();
xhttp.open('GET', path, true);
xhttp.onreadystatechange = function() {
if (this.readyState === 4) {
if ((this.status >= 200 && this.status < 300) || this.status === 304) {
var response = JSON.parse(this.responseText);
resolve(response);
} else {
var error = this.statusText;
reject('Http/App Error: ' + error);
}
}
}
xhttp.onerror = processError;
xhttp.onabort = processError;
xhttp.send();
xhttp = null;
function processError(err) {
reject('Network Error: ' + err.target.status);
}
});
}
const ask = document.getElementById('ask-weather')
const weather = document.getElementById('weather-result')
const endpoint = 'https://www.prevision-meteo.ch/services/json/paris'
ask.addEventListener('click', function() {
getJSON(endpoint).then((success) => {
const response = success.current_condition.condition
weather.innerHTML = response
}, (error) => {
console.log(error)
})
})
This is a simple example using Promise. See the fiddle working.

XMLHttpRequest file upload returning a 500 error

I am trying to upload a file using XMLHttpRequest() but the post request is returning a 500 internal server error. I've made sure the file parameter is sending through the file object and that the action URL is correct. Am I missing something?
HTML:
<input type="file" class="form-control" name="documents" (change)="onFileUploadChange($event)">
Component:
onFileUploadChange(_event: any) {
let file = _event.srcElement.files;
let postData: any = null;
this._fileUploadService.uploadFile(this.uploadURL, file);
}
Service:
uploadFile(_url:string,_file:File):Promise<any> {
return new Promise((resolve, reject) => {
var xhr:XMLHttpRequest = new XMLHttpRequest();
console.log(_file);
console.log(_file[0].name);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
// ...
} else if (xhr.status === 500) {
// ...
}
else {
// ...
}
}
};
var formData = new FormData();
formData.append('file', _file[0], _file[0].name);
xhr.open('POST', _url, true);
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
xhr.setRequestHeader('Content-Type','multipart/form-data');
xhr.send(formData);
});
}
A 500 error means the request got to the destination and there was a problem at the destination. Try checking the destination for errors.
Maybe you send wrong request? Last time I've got the same problem and there was a solution:
Saving Blob as xlsx in Angular2

Create js variable to hold remote JSON data [duplicate]

I need to do an HTTP GET request in JavaScript. What's the best way to do that?
I need to do this in a Mac OS X dashcode widget.
Browsers (and Dashcode) provide an XMLHttpRequest object which can be used to make HTTP requests from JavaScript:
function httpGet(theUrl)
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false ); // false for synchronous request
xmlHttp.send( null );
return xmlHttp.responseText;
}
However, synchronous requests are discouraged and will generate a warning along the lines of:
Note: Starting with Gecko 30.0 (Firefox 30.0 / Thunderbird 30.0 / SeaMonkey 2.27), synchronous requests on the main thread have been deprecated due to the negative effects to the user experience.
You should make an asynchronous request and handle the response inside an event handler.
function httpGetAsync(theUrl, callback)
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = function() {
if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
callback(xmlHttp.responseText);
}
xmlHttp.open("GET", theUrl, true); // true for asynchronous
xmlHttp.send(null);
}
window.fetch is a modern replacement for XMLHttpRequest that makes use of ES6 promises. There's a nice explanation here, but it boils down to (from the article):
fetch(url).then(function(response) {
return response.json();
}).then(function(data) {
console.log(data);
}).catch(function(err) {
console.log('Fetch Error :-S', err);
});
Browser support has been good since 2017. IE will likely not get official support. GitHub has a polyfill available adds support to some legacy browsers (esp versions of Safari pre March 2017 and mobile browsers from the same period).
I guess whether this is more convenient than jQuery or XMLHttpRequest or not depends on the nature of the project.
Here's a link to the spec https://fetch.spec.whatwg.org/
Edit:
Using ES7 async/await, this becomes simply (based on this Gist):
async function fetchAsync (url) {
let response = await fetch(url);
let data = await response.json();
return data;
}
In jQuery:
$.get(
"somepage.php",
{paramOne : 1, paramX : 'abc'},
function(data) {
alert('page content: ' + data);
}
);
Lots of great advice above, but not very reusable, and too often filled with DOM nonsense and other fluff that hides the easy code.
Here's a Javascript class we created that's reusable and easy to use. Currently it only has a GET method, but that works for us. Adding a POST shouldn't tax anyone's skills.
var HttpClient = function() {
this.get = function(aUrl, aCallback) {
var anHttpRequest = new XMLHttpRequest();
anHttpRequest.onreadystatechange = function() {
if (anHttpRequest.readyState == 4 && anHttpRequest.status == 200)
aCallback(anHttpRequest.responseText);
}
anHttpRequest.open( "GET", aUrl, true );
anHttpRequest.send( null );
}
}
Using it is as easy as:
var client = new HttpClient();
client.get('http://some/thing?with=arguments', function(response) {
// do something with response
});
A version without callback
var i = document.createElement("img");
i.src = "/your/GET/url?params=here";
Here is code to do it directly with JavaScript. But, as previously mentioned, you'd be much better off with a JavaScript library. My favorite is jQuery.
In the case below, an ASPX page (that's servicing as a poor man's REST service) is being called to return a JavaScript JSON object.
var xmlHttp = null;
function GetCustomerInfo()
{
var CustomerNumber = document.getElementById( "TextBoxCustomerNumber" ).value;
var Url = "GetCustomerInfoAsJson.aspx?number=" + CustomerNumber;
xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = ProcessRequest;
xmlHttp.open( "GET", Url, true );
xmlHttp.send( null );
}
function ProcessRequest()
{
if ( xmlHttp.readyState == 4 && xmlHttp.status == 200 )
{
if ( xmlHttp.responseText == "Not found" )
{
document.getElementById( "TextBoxCustomerName" ).value = "Not found";
document.getElementById( "TextBoxCustomerAddress" ).value = "";
}
else
{
var info = eval ( "(" + xmlHttp.responseText + ")" );
// No parsing necessary with JSON!
document.getElementById( "TextBoxCustomerName" ).value = info.jsonData[ 0 ].cmname;
document.getElementById( "TextBoxCustomerAddress" ).value = info.jsonData[ 0 ].cmaddr1;
}
}
}
A copy-paste modern version ( using fetch and arrow function ) :
//Option with catch
fetch( textURL )
.then(async r=> console.log(await r.text()))
.catch(e=>console.error('Boo...' + e));
//No fear...
(async () =>
console.log(
(await (await fetch( jsonURL )).json())
)
)();
A copy-paste classic version:
let request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (this.readyState === 4) {
if (this.status === 200) {
document.body.className = 'ok';
console.log(this.responseText);
} else if (this.response == null && this.status === 0) {
document.body.className = 'error offline';
console.log("The computer appears to be offline.");
} else {
document.body.className = 'error';
}
}
};
request.open("GET", url, true);
request.send(null);
Short and clean:
const http = new XMLHttpRequest()
http.open("GET", "https://api.lyrics.ovh/v1/toto/africa")
http.send()
http.onload = () => console.log(http.responseText)
IE will cache URLs in order to make loading faster, but if you're, say, polling a server at intervals trying to get new information, IE will cache that URL and will likely return the same data set you've always had.
Regardless of how you end up doing your GET request - vanilla JavaScript, Prototype, jQuery, etc - make sure that you put a mechanism in place to combat caching. In order to combat that, append a unique token to the end of the URL you're going to be hitting. This can be done by:
var sURL = '/your/url.html?' + (new Date()).getTime();
This will append a unique timestamp to the end of the URL and will prevent any caching from happening.
Modern, clean and shortest
fetch('https://baconipsum.com/api/?type=1')
let url = 'https://baconipsum.com/api/?type=all-meat&paras=1&start-with-lorem=2';
// to only send GET request without waiting for response just call
fetch(url);
// to wait for results use 'then'
fetch(url).then(r=> r.json().then(j=> console.log('\nREQUEST 2',j)));
// or async/await
(async()=>
console.log('\nREQUEST 3', await(await fetch(url)).json())
)();
Open Chrome console network tab to see request
Prototype makes it dead simple
new Ajax.Request( '/myurl', {
method: 'get',
parameters: { 'param1': 'value1'},
onSuccess: function(response){
alert(response.responseText);
},
onFailure: function(){
alert('ERROR');
}
});
One solution supporting older browsers:
function httpRequest() {
var ajax = null,
response = null,
self = this;
this.method = null;
this.url = null;
this.async = true;
this.data = null;
this.send = function() {
ajax.open(this.method, this.url, this.asnyc);
ajax.send(this.data);
};
if(window.XMLHttpRequest) {
ajax = new XMLHttpRequest();
}
else if(window.ActiveXObject) {
try {
ajax = new ActiveXObject("Msxml2.XMLHTTP.6.0");
}
catch(e) {
try {
ajax = new ActiveXObject("Msxml2.XMLHTTP.3.0");
}
catch(error) {
self.fail("not supported");
}
}
}
if(ajax == null) {
return false;
}
ajax.onreadystatechange = function() {
if(this.readyState == 4) {
if(this.status == 200) {
self.success(this.responseText);
}
else {
self.fail(this.status + " - " + this.statusText);
}
}
};
}
Maybe somewhat overkill but you definitely go safe with this code.
Usage:
//create request with its porperties
var request = new httpRequest();
request.method = "GET";
request.url = "https://example.com/api?parameter=value";
//create callback for success containing the response
request.success = function(response) {
console.log(response);
};
//and a fail callback containing the error
request.fail = function(error) {
console.log(error);
};
//and finally send it away
request.send();
To do this Fetch API is the recommended approach, using JavaScript Promises. XMLHttpRequest (XHR), IFrame object or dynamic <script> tags are older (and clunkier) approaches.
<script type=“text/javascript”>
// Create request object
var request = new Request('https://example.com/api/...',
{ method: 'POST',
body: {'name': 'Klaus'},
headers: new Headers({ 'Content-Type': 'application/json' })
});
// Now use it!
fetch(request)
.then(resp => {
// handle response
})
.catch(err => {
// handle errors
});
</script>
Here is a great fetch demo and MDN docs
I'm not familiar with Mac OS Dashcode Widgets, but if they let you use JavaScript libraries and support XMLHttpRequests, I'd use jQuery and do something like this:
var page_content;
$.get( "somepage.php", function(data){
page_content = data;
});
SET OF FUNCTIONS RECIPES EASY AND SIMPLE
I prepared a set of functions that are somehow similar but yet demonstrate new functionality as well as the simplicity that Javascript has reached if you know how to take advantage of it.
Let some basic constants
let data;
const URLAPI = "https://gorest.co.in/public/v1/users";
function setData(dt) {
data = dt;
}
Most simple
// MOST SIMPLE ONE
function makeRequest1() {
fetch(URLAPI)
.then(response => response.json()).then( json => setData(json))
.catch(error => console.error(error))
.finally(() => {
console.log("Data received 1 --> ", data);
data = null;
});
}
Variations using Promises and Async facilities
// ASYNC FUNCTIONS
function makeRequest2() {
fetch(URLAPI)
.then(async response => await response.json()).then(async json => await setData(json))
.catch(error => console.error(error))
.finally(() => {
console.log("Data received 2 --> ", data);
data = null;
});
}
function makeRequest3() {
fetch(URLAPI)
.then(async response => await response.json()).then(json => setData(json))
.catch(error => console.error(error))
.finally(() => {
console.log("Data received 3 --> ", data);
data = null;
});
}
// Better Promise usages
function makeRequest4() {
const response = Promise.resolve(fetch(URLAPI).then(response => response.json())).then(json => setData(json) ).finally(()=> {
console.log("Data received 4 --> ", data);
})
}
Demostration of one liner function!!!
// ONE LINER STRIKE ASYNC WRAPPER FUNCTION
async function makeRequest5() {
console.log("Data received 5 -->", await Promise.resolve(fetch(URLAPI).then(response => response.json().then(json => json ))) );
}
WORTH MENTION ---> #Daniel De León propably the cleanest function*
(async () =>
console.log(
(await (await fetch( URLAPI )).json())
)
)();
The top answer -> By #tggagne shows functionality with HttpClient API.
The same can be achieve with Fetch. As per this Using Fetch by MDN shows how you can pass a INIT as second argument, basically opening the possibility to configure easily an API with classic methods (get, post...) .
// Example POST method implementation:
async function postData(url = '', data = {}) {
// Default options are marked with *
const response = await fetch(url, {
method: 'POST', // *GET, POST, PUT, DELETE, etc.
mode: 'cors', // no-cors, *cors, same-origin
cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: 'same-origin', // include, *same-origin, omit
headers: {
'Content-Type': 'application/json'
// 'Content-Type': 'application/x-www-form-urlencoded',
},
redirect: 'follow', // manual, *follow, error
referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
body: JSON.stringify(data) // body data type must match "Content-Type" header
});
return response.json(); // parses JSON response into native JavaScript objects
}
postData('https://example.com/answer', { answer: 42 })
.then(data => {
console.log(data); // JSON data parsed by `data.json()` call
});
Node
Fetch is not available on Node (Server Side)
The easiest solution (end of 2021) is to use Axios.
$ npm install axios
Then Run:
const axios = require('axios');
const request = async (url) => await (await axios.get( url ));
let response = request(URL).then(resp => console.log(resp.data));
In your widget's Info.plist file, don't forget to set your AllowNetworkAccess key to true.
For those who use AngularJs, it's $http.get:
$http.get('/someUrl').
success(function(data, status, headers, config) {
// this callback will be called asynchronously
// when the response is available
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
You can get an HTTP GET request in two ways:
This approach based on xml format. You have to pass the URL for the request.
xmlhttp.open("GET","URL",true);
xmlhttp.send();
This one is based on jQuery. You have to specify the URL and function_name you want to call.
$("btn").click(function() {
$.ajax({url: "demo_test.txt", success: function_name(result) {
$("#innerdiv").html(result);
}});
});
The best way is to use AJAX ( you can find a simple tutorial on this page Tizag). The reason is that any other technique you may use requires more code, it is not guaranteed to work cross browser without rework and requires you use more client memory by opening hidden pages inside frames passing urls parsing their data and closing them.
AJAX is the way to go in this situation. That my two years of javascript heavy development speaking.
now with asynchronus js we can use this method with fetch() method to make promises in a more concise way. Async functions are supported in all modern browsers.
async function funcName(url){
const response = await fetch(url);
var data = await response.json();
}
function get(path) {
var form = document.createElement("form");
form.setAttribute("method", "get");
form.setAttribute("action", path);
document.body.appendChild(form);
form.submit();
}
get('/my/url/')
Same thing can be done for post request as well.
Have a look at this link JavaScript post request like a form submit
To refresh best answer from joann with promise this is my code:
let httpRequestAsync = (method, url) => {
return new Promise(function (resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = function () {
if (xhr.status == 200) {
resolve(xhr.responseText);
}
else {
reject(new Error(xhr.responseText));
}
};
xhr.send();
});
}
Simple async request:
function get(url, callback) {
var getRequest = new XMLHttpRequest();
getRequest.open("get", url, true);
getRequest.addEventListener("readystatechange", function() {
if (getRequest.readyState === 4 && getRequest.status === 200) {
callback(getRequest.responseText);
}
});
getRequest.send();
}
Ajax
You'd be best off using a library such as Prototype or jQuery.
// Create a request variable and assign a new XMLHttpRequest object to it.
var request = new XMLHttpRequest()
// Open a new connection, using the GET request on the URL endpoint
request.open('GET', 'restUrl', true)
request.onload = function () {
// Begin accessing JSON data here
}
// Send request
request.send()
In pure javascript and returning a Promise:
httpRequest = (url, method = 'GET') => {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open(method, url);
xhr.onload = () => {
if (xhr.status === 200) { resolve(xhr.responseText); }
else { reject(new Error(xhr.responseText)); }
};
xhr.send();
});
}
If you want to use the code for a Dashboard widget, and you don't want to include a JavaScript library in every widget you created, then you can use the object XMLHttpRequest that Safari natively supports.
As reported by Andrew Hedges, a widget doesn't have access to a network, by default; you need to change that setting in the info.plist associated with the widget.
You can do it with pure JS too:
// Create the XHR object.
function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
// XHR for Chrome/Firefox/Opera/Safari.
xhr.open(method, url, true);
} else if (typeof XDomainRequest != "undefined") {
// XDomainRequest for IE.
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
// CORS not supported.
xhr = null;
}
return xhr;
}
// Make the actual CORS request.
function makeCorsRequest() {
// This is a sample server that supports CORS.
var url = 'http://html5rocks-cors.s3-website-us-east-1.amazonaws.com/index.html';
var xhr = createCORSRequest('GET', url);
if (!xhr) {
alert('CORS not supported');
return;
}
// Response handlers.
xhr.onload = function() {
var text = xhr.responseText;
alert('Response from CORS request to ' + url + ': ' + text);
};
xhr.onerror = function() {
alert('Woops, there was an error making the request.');
};
xhr.send();
}
See: for more details: html5rocks tutorial
Here is an alternative to xml files to load your files as an object and access properties as an object in a very fast way.
Attention, so that javascript can him and to interpret the content correctly it is necessary to save your files in the same format as your HTML page. If you use UTF 8 save your files in UTF8, etc.
XML works as a tree ok? instead of writing
<property> value <property>
write a simple file like this:
Property1: value
Property2: value
etc.
Save your file ..
Now call the function ....
var objectfile = {};
function getfilecontent(url){
var cli = new XMLHttpRequest();
cli.onload = function(){
if((this.status == 200 || this.status == 0) && this.responseText != null) {
var r = this.responseText;
var b=(r.indexOf('\n')?'\n':r.indexOf('\r')?'\r':'');
if(b.length){
if(b=='\n'){var j=r.toString().replace(/\r/gi,'');}else{var j=r.toString().replace(/\n/gi,'');}
r=j.split(b);
r=r.filter(function(val){if( val == '' || val == NaN || val == undefined || val == null ){return false;}return true;});
r = r.map(f => f.trim());
}
if(r.length > 0){
for(var i=0; i<r.length; i++){
var m = r[i].split(':');
if(m.length>1){
var mname = m[0];
var n = m.shift();
var ivalue = m.join(':');
objectfile[mname]=ivalue;
}
}
}
}
}
cli.open("GET", url);
cli.send();
}
now you can get your values efficiently.
getfilecontent('mesite.com/mefile.txt');
window.onload = function(){
if(objectfile !== null){
alert (objectfile.property1.value);
}
}
It's just a small gift to contibute to the group. Thanks of your like :)
If you want to test the function on your PC locally, restart your browser with the following command (supported by all browsers except safari):
yournavigator.exe '' --allow-file-access-from-files
<button type="button" onclick="loadXMLDoc()"> GET CONTENT</button>
<script>
function loadXMLDoc() {
var xmlhttp = new XMLHttpRequest();
var url = "<Enter URL>";``
xmlhttp.onload = function () {
if (xmlhttp.readyState == 4 && xmlhttp.status == "200") {
document.getElementById("demo").innerHTML = this.responseText;
}
}
xmlhttp.open("GET", url, true);
xmlhttp.send();
}
</script>

Categories