First of all. Code of ajax_handler.php
<?php
$res = $_POST;
$res['response'] = 'Custom';
header('Content-Type: application/json');
echo json_encode($res);
I have jQuery Ajax function with Promise
wrapper like this.
const _sendAjax = async (url, params = {}, dataType = 'json', method = 'POST') => new Promise(async (accept, reject) => {
if (url.trim().length < 1)
return reject('Invalid Url');
method = method.trim().toUpperCase();
if (!['POST', 'GET'].includes(method))
return reject('Invalid Ajax Method');
let u = new URL(url, window.location.href);
u.searchParams.set('upd', Math.random() * 1000 + new Date().getMilliseconds());
url = u.toString();
$.ajax({
url: url,
type: method,
processData: true,
dataType: dataType,
data: params,
success: data => accept(data),
error: (request, status, error) => {
reject({ request, status, error });
}
});
});
// Callings
_sendAjax('ajax_handler.php', { a: 22, b: 23 }).then(res => console.log(res)).catch(error => console.error(error));// {"a":"22","b":"23","response":"Custom"}
_sendAjax('ajax_handler.php', { a: [1, 2, 3, 4], b: 23 }).then(res => console.log(res)).catch(error => console.error(error));// {"a":["1","2","3","4"],"b":"23","response":"Custom"}
_sendAjax('ajax_handler.php', { a: { c: [1, 2, 3, 4], d: 45 }, b: 23 }).then(res => console.log(res)).catch(error => console.error(error)); // {"a":{"c":["1","2","3","4"],"d":"45"},"b":"23","response":"Custom"}
Responses (Respectively)
console.log({"a":"22","b":"23","response":"Custom"});
console.log({"a":["1","2","3","4"],"b":"23","response":"Custom"});
console.log({"a":{"c":["1","2","3","4"],"d":"45"},"b":"23","response":"Custom"});
See, the variation in submitted data as params
I tried to convert this function to JS Fetch Api.
const _sendFetch = async (url, params = {}, dataType = 'json', method = 'POST') => new Promise(async (accept, reject) => {
if (url.trim().length < 1)
return reject('Invalid Url');
method = method.trim().toUpperCase();
if (!['POST', 'GET'].includes(method))
return reject('Invalid Ajax Method');
let u = new URL(url, window.location.href);
u.searchParams.set('upd', Math.random() * 1000 + new Date().getMilliseconds());
let fetchOptions = {
credentials: 'include',
cache: 'no-store',
redirect: 'follow',
method: method,
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
}
}
if (Object.keys(params).length)
if (method === 'POST')
fetchOptions.body = Object.keys(params).map(x => encodeURIComponent(x) + '=' + encodeURIComponent(params[x])).join('&');
else if (method === 'GET')
Object.keys(params).forEach(x => u.searchParams.set(encodeURIComponent(x), encodeURIComponent(params[x])));
url = u.toString();
return fetch(url, fetchOptions)
.then(res => (res.status === 200 && res.ok) ? res : reject(res))
.then(res => dataType === 'json' ? accept(res.json()) : accept(res.text()))
.catch(error => reject(error));
});
// Callings
_sendFetch('ajax_handler.php', { a: 22, b: 23 }).then(res => console.log(res)).catch(error => console.error(error)); // {"a":"22","b":"23","response":"Custom"}
_sendFetch('ajax_handler.php', { a: [1, 2, 3, 4], b: 23 }).then(res => console.log(res)).catch(error => console.error(error)); // {"a":"1,2,3,4","b":"23","response":"Custom"}
_sendFetch('ajax_handler.php', { a: { c: [1, 2, 3, 4], d: 45 }, b: 23 }).then(res => console.log(res)).catch(error => console.error(error)); // {"a":"[object Object]","b":"23","response":"Custom"}
Responses (Respectively)
console.log({"a":"22","b":"23","response":"Custom"});
console.log({"a":"1,2,3,4","b":"23","response":"Custom"});
console.log({"a":"[object Object]","b":"23","response":"Custom"});
Problem:
Obviously, I can’t process and send inputted data as jQuery is doing because of processData: true,
. jQuery seem to handle data efficiently for both POST
as well as GET
.
I can’t to figure out a way to replicate working of processData
functionality of jQuery Ajax as the params
have lots of variation and I need some generic code to process inputted data for Fetch as jQuery does.
I want to do this in JS only without third party libraries like jQuery.
Advertisement
Answer
I did mention that I only want the solution in JS but as commented by @CBore
that I have few options in this matter.
- Write my own recursive function.
- Use URLSearchParams as described here. But this is not working for my scenario as the params are not just simple object.
console.log(new URLSearchParams({ a: { c: [1, 2, 3, 4], d: 45 }, b: 23 }).toString());
- Use jQuery.param. But I do not want to use a full library just for a single function / advantage.
- Use light-weight library like jquery-param.
So in the end, I have settled for jquery-param for the time being.