FormData is putting the string "null" for null values

3

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

I'm doing this upload as follows:

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

But when I receive this data on the server, it is being sent as an undue string.

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 that this seems to be a problem with FormData .

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 does not do a correct substitution of the values, what is the solution that I could apply for the values to be sent correctly?

This is disrupting server side validation because it is sending "null" instead of sending nothing. For example, the phone field, which has to be in the correct format but not required, if the value is empty, is valid.

    
asked by anonymous 25.01.2017 / 17:16

1 answer

2

You can not send "primitive" values unless you use a format like JSON and decode when you get to the server, everything that is sent over HTTP will be text or "binary."

This is the reason why there are methods like Json, Xml and serialization , in order to send the data in a standard format which can be interpreted in the backend or front end (depends on where to send). Then you can do 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 so:

$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 to 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 you can filter the items before, but as I do not 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 do not understand anything about Angular.js, but I believe that using the Upload plugin would be simply 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 it were to be transported via Xml, for example to a WebService that supports SOAP could use the attribute xsi:nil " (requires the namespace xmlns:xsi="w3.org/2001/XMLSchema-instance" ), so 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 get away from the subject, but it's just to explain the serialization, in SOAP version 1.1 (I'm really not sure if it's something supported) indicates that you can use xsd:null="true" .

Of course you can create your own Xml and send via Ajax maybe, including up image data in base64 , will be a little painful, but it's just for understanding even, 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 back end you decode and you can use SimpleXMLElement if it is php for example, of course will have to parse manually using the type="" attribute and the contents of the <item> tag

    
25.01.2017 / 17:40