Skip to content
Advertisement

Process inputted data for JS Fetch Api request like jQuery does in Ajax request when processData is true

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.

  1. Write my own recursive function.
  2. 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());
  1. Use jQuery.param. But I do not want to use a full library just for a single function / advantage.
  2. Use light-weight library like jquery-param.

So in the end, I have settled for jquery-param for the time being.

User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement