Skip to content
Advertisement

Sending data alongside FormData as one Object in AJAX

I’m trying to pass a FormData inside a JSON array to an AJAX script:

$('#form').submit(function(e)
{
    e.preventDefault();

    let formData = new FormData(this),
        data = {'action': 'insert', 'data': formData};

    $.ajax({
        data: data,
        url: '/wp-content/plugins/eng-dealer-map/bin/Admin.php',
        type: 'post',
        cache: false,
        contentType: false,
        processData: false,
        success: function(res) {console.log(res)},
        error: function(res) {console.log(res)}
    })
});

Then /bin/Admin.php

<?php
    ini_set('display_errors',1);
    ini_set('display_startup_errors',1);
    error_reporting(-1);

    $ds = DIRECTORY_SEPARATOR;

    require_once $_SERVER['DOCUMENT_ROOT']. $ds. 'wp-content'. $ds. 'plugins'. $ds. 'eng-dealer-map'. $ds. 'vendor'. $ds. 'autoload.php';

    var_dump($_POST);
    $admin = new AppEndpointAdmin(['action' => $_POST['action'], 'data' => $_POST['data']]);
    echo $admin->execute();

Which, in turn, finally goes to this (minified) class:

<?php
    namespace AppEndpoint;

    class Admin
    {
        protected $db;
        protected $table;

        protected $sql;
        protected $data;

        public function __construct($foo)
        {
            require_once $_SERVER['DOCUMENT_ROOT']. DIRECTORY_SEPARATOR. 'wp-config.php';
            global $wpdb;

            $this->db = $wpdb;
            $this->table = '`'. $this->db->prefix .'trey_is_the_best`';

            $this->sql = $this->build($foo['action']);
            $this->data = $foo['data'];
        }

        public function build(string $action)
        {
            switch($action)
            {
                case 'insert': return $this->insertSql(); break;
                case 'update': return $this->updateSql(); break;
                case 'remove': return $this->removeSql(); break;
                default: throw new Exception('trey'); break;
            }
        }

        public function execute()
        {
            if (!empty($this->sql)) {
                try {
                    if ($this->db->query($this->db->prepare($this->sql, $this->data))) {
                        return true;
                    } else {
                        throw new Exception($this->db->last_error);
                    }
                } catch (Exception $e) {
                    throw new Exception($e->getMessage());
                }
            } else {
                return 'SQL empty!';
            }
        }
    }

Unfortunately, it seems $_POST gets lost along the way. Adding this in my JS:

for (let pair of formData.entries())
{
    console.log(pair[0]+ ', ' + pair[1]);
}

which shows my data correctly. I then var_dump($_POST) in bin/Admin.php which shows an empty array.

I changed 'data': formData to 'data': 'hello, world' so I have a feeling FormData doesn’t like being inside a JSON array with other elements?

So how do I send FormData with other elements to my AJAX script? I know I could use:

formData.append('action', 'action-value')

but that feels like it’s an extra step when it could just been sent as one object to my script.

I also tried using JSON.stringify on formData but again, nothing. Is there a way I can send formData alongside other data as one object without using .append()? Or is that my only option?

Advertisement

Answer

I have a feeling FormData doesn’t like being inside a JSON array with other elements?

Correct. You can’t convert FormData to JSON.

So how do I send FormData with other elements to my AJAX script?

Add the extra data to the FormData.

I know I could use:

formData.append('action', 'action-value')

Yes, do that.

but that feels like it’s an extra step when it could just been sent as one object to my script.

The FormData object is one object. You just need to add the data to it instead of adding the data to a different object and then trying to add the data from FormData to it.

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