vanillajs fetch() examples ¶
Fetching JSON with JavaScript Fetch API
Quick and easy:
fetch('https://reqbin.com/echo/get/json', { method: 'GET', headers: { 'Accept': 'application/json', }, }) .then(response => response.json()) .then(response => console.log(JSON.stringify(response)))
Example 1
The following is more elaborated with the purpose to collect all errors is a single catch handler:
- either if a network error occurs,
- or if the response is not 200-OK
In the latter case, the response might contain further details JSON-serialized and we want to inspect them
fetch( '/backend/j/mto_evaluate_final_stock_total', { method: "post", body: data, mode: 'cors', // 'no-cors', cache: 'no-cache', credentials: 'same-origin', headers: { // make sure request.is_ajax() return True on the server 'X-Requested-With': 'XMLHttpRequest', 'X-CSRFToken': getCookie('csrftoken') } } ) .then(function(response) { if (response.ok) { return response.json() } // if not 200-OK, reject instead of throw // Here, the plan is to get {status: 4XX, message: 'a message'} format as a result in both cases. // See: https://stackoverflow.com/questions/38235715/fetch-reject-promise-and-catch-the-error-if-status-is-not-ok#67660773 return Promise.reject(response) }) .then(function(data) { console.log(data) ... use data ... }) .catch(function(error) { // Show error console.error(error.status, error.statusText); // also get error messages, if any // Again, see: https://stackoverflow.com/questions/38235715/fetch-reject-promise-and-catch-the-error-if-status-is-not-ok#67660773 error.json().then(function(json) { console.error(json); }) }) .finally(function() { })
Example 2
// bind to the form’s submit event form.addEventListener('submit', function(event) { // prevent the form from performing its default submit action event.preventDefault(); header.classList.add('loading'); // serialize the form’s content and send via an AJAX call // using the form’s defined method and action let url = form.getAttribute('action') || self.options.url; let method = form.getAttribute('method') || 'post'; // We use FormData // to allow files upload (i.e. process <input type="file"> as expected) // Note that, using FormData, we also need (with jQuery): // - processData: false // - contentType: false let data = new FormData(form); //console.log('form data: %o', new URLSearchParams(data).toString()); self._notify('submitting', {method: method, url: url, data:data}); let promise = fetch( self.options.url, { method: "post", body: data, mode: 'cors', // 'no-cors', cache: 'no-cache', credentials: 'same-origin', headers: { // make sure request.is_ajax() return True on the server 'X-Requested-With': 'XMLHttpRequest', 'X-CSRFToken': getCookie('csrftoken') } } ); promise.then(response => { if (response.ok) { // Upon receiving a JSON response, we assume that the form has been validated, // so we can close the modal if (response.headers.get('Content-Type') === 'application/json') { response.json().then(data => { self._notify('submitted', {method: method, url: url, data: data}); self.close(); }) .catch(error => { FrontendForms.display_server_error(error); }) } else { response.text().then(data => { // update the modal body with the new form body.innerHTML = data; // Does the response contain a form ? let form = self.element.querySelector('.dialog-content .dialog-body form'); if (form !== null) { // If the server sends back a successful response, // we need to further check the HTML received // If xhr contains any field errors, // the form did not validate successfully, // so we keep it open for further editing //if (jQuery(xhr).find('.has-error').length > 0) { if (form.querySelectorAll('.has-error').length > 0 || form.querySelectorAll('.errorlist').length > 0) { self._notify('loaded', {url: url}); self._form_ajax_submit(true); } else { // otherwise, we've done and can close the modal self._notify('submitted', {method: method, url: url, data: data}); self.close(); } } // If not, assume we received a feedback for the user after successfull submission, so: // - keep the dialog open // - hide the save button else { // We also notify the user about successful submission self._notify('submitted', {method: method, url: url, data: data}); btn_save.style.display = 'none'; } }); } } else { self._notify('submission_failure', {method: method, url: url, data: data, error: response.statusText}); FrontendForms.display_server_error(response.statusText); } }).catch(error => { self._notify('submission_failure', {method: method, url: url, data: data, error:error}); FrontendForms.display_server_error(error.toString()); }).finally(() => { header.classList.remove('loading'); });
where:
function getCookie(name) { var value = '; ' + document.cookie, parts = value.split('; ' + name + '='); if (parts.length == 2) return parts.pop().split(';').shift(); }