javascript – FormData is putting the string "null" to null values

Question:

I'm using a library called ngUpload . In it we have the option to send the data along with the upload of a specific file.

I'm uploading as follows:

Upload.upload({
    url: '/orcamento/ajax-criar', 
    data: {cliente: $scope.cliente, orcamento: $scope.orcamento}
})

However, when I receive this data on the server, they are being sent as a string improperly.

Example:

 var_dump(
  $request->request->get('cliente')['cadastrado']
 ); 

 // Retorna: string(4)'true'

 var_dump(
  $request->request->get('cliente')['telefone']
 ); 

 // Retorna: string(4)'null'

I noticed this seems to be a FormData issue.

Example:

f = new FormData;

f.append('null_value', null);
f.append('boolean_value', false);

console.log(f.get('null_value'), typeof f.get('null_value'));

console.log(f.get('boolean_value'), typeof f.get('boolean_value'));

In this case, since FormData doesn't do a correct replacement of the values, what is the solution I could apply so that the values ​​are sent correctly?

This is hampering server-side validation due to the fact that it is sending "null" instead of not sending anything. For example, the telephone field, which must have the correct format but is not mandatory, if the value is empty, is valid.

Answer:

There is no way to send "primitive" values ​​unless you use a format like JSON and decode when it gets to the server, everything that is sent via HTTP will be text or "binary".

Precisely for this reason there are methods such as Json, Xml and serialization , to be able to send the data in a standard format which can be interpreted in the back-end or front-end (depends on where to send it). So you can do it like this:

var f = new FormData;

data = { "telefone": null, "nome": "Wallace" };

f.append('data', JSON.stringify(data));

//Ainda string
console.log(f.get("data"));

//Decodificado
var parsed = JSON.parse(f.get("data"));

console.log(parsed.nome, parsed.telefone);

And when you get to the back-end, do this:

$data = json_decode($request->request->get('cliente')['data']);

var_dump($data);

Or if it's pure PHP:

$data = json_decode($_POST['data']);

var_dump($data);

Using only strings

Another way would be when it is NULL simply change the value to an empty string and when it is false do not add the item to FormData , being angular.js I believe I can filter the items before, but as I don't understand this the basic explanation would be this:

function appendToForm(form, key, value)
{
    if (value === null) { //Null é vazio
       form.append(key, "");
    } else if (value === false || typeof value === "undefined") {//False e undefined é desconsiderado
       form.append(key, value);
    } else if (value === true) { //True vira 1
       form.append(key, "1");
    } else {//Outros valores viram string se necessário
       form.append(key, value);
    }
}

var f = new FormData;

appendToForm(f, "nome", "JBueno ♥ JavaScript");
appendToForm(f, "telefone", null);

for (var k of f.keys()) {
   var value = f.get(k);
   console.log(k, "=>", value, ',tipo =>' + typeof value);
}

I don't understand anything about Angular.js, but I think using the Upload plugin would be just like this:

function appendToForm(data, key, value)
{
    if (value === null) {
       data[key] = "";
    } else if (value === false || typeof value === "undefined") {
       data[key] = value;
    } else if (value === true) {
       data[key] = "1";
    } else {
       data[key] = value;
    }
}

...

var data = {};

appendToForm('cliente', $scope.cliente);
appendToForm('orcamento', $scope.orcamento);

Upload.upload({
    url: '/orcamento/ajax-criar', 
    data: data
})

XML

If you were to transport via Xml, for example to a WebService that supports SOAP, you could use the xsi:nil attribute (requires the namespace xmlns:xsi="w3.org/2001/XMLSchema-instance" ), like this for example:

<tag xsi:nil="true" />
<tag xsi:nil="false" />
<tag xsi:nil="null" />

You can also take a look at w3.org , I know it's straying from the subject, but that's just to explain serialization, in SOAP version 1.1 (I'm not really sure if it's supported) indicates that you can use xsd:null="true" .

Of course you can create your own Xml and send it via Ajax maybe, including even the base64 image data, it will be a little laborious, but it's just for understanding, for example:

<?xml version="1.0"?>
<upload>
    <item type="bin" name="foto">base64 com o conteudo do upload</item>
    <item type="bool" name="possui_carro">true</item>
    <item type="bool" name="possui_moto">false</item>
    <item type="null" name="telefone" />
    <item name="hello_world">olá, mundo!</item> <!-- para string pode omitir o type ou adicionar type="string" -->
</upload>

And on the backend you decode and can use SimpleXMLElement if it's php for example, of course you'll have to parse it manually using the type="" attribute and the content of the <item> tag

Scroll to Top