Reputation: 1234
How can the Symfony Serializer Component be configured to normalize a float property of an object (entity)?
In detail: the taxRate
property of a doctrine entity is is mapped to a PHP float value. And I would like to respond from a controller with a JSON representation like:
{taxRate:0.19}
But what I get is
{taxRate:"0.19"}
The definition of the entity's property and annotations are:
class ExampleEntity {
/**
* @ORM\Column(type="decimal", precision=3, scale=2, nullable=true)
* @Groups({"api"})
*/
protected $taxRate;
}
The controller looks like this:
$serializer = $this->get('serializer');
return new JsonResponse(
$serializer->normalize(
$exampleEntity,
'json',
[
'groups' => 'api',
]
)
);
I don't like the solution of converting the string into a Float on the JavaScript side. My app would like to assert the property is NULL or a Float value.
How can this be done?
Upvotes: 4
Views: 5105
Reputation: 1646
For decimal type values retrieved from the database are always converted to PHP's string type or null if no data is present.
If you want to use decimal, change the getter for property
public function getTaxRage(): ?float
{
return is_string($this->taxRate) ? (float) $this->taxRate : $this->taxRate;
}
Upvotes: 0
Reputation: 116
I had the same issue with Symfony 4.4 serializer, and I disagree with your solution. I resolved my problem by changing type="decimal" to type="float", as some people already suggested it in the comments. A proper type hinting is a good practice. Why using a string when you can use a float?
Float type, from doctrine documentation :
https://www.doctrine-project.org/projects/doctrine-dbal/en/2.12/reference/types.html#types
Maps and converts numeric data with floating-point precision. If you only need an approximate precision for numbers with fractions, you should consider using this type. Values retrieved from the database are always converted to PHP's float/double type or null if no data is present.
Some additionnal information about this approach :
A float attribute example for the serializer :
/**
* @var float|null
* @ORM\Column(type="float", precision=6, scale=2, nullable=true)
*/
protected $ratio;
/**
* @return float|null
*/
public function getRatio(): ?float
{
return $this->ratio;
}
/**
* @param float|null $ratio
* @return $this
*/
public function setRatio(?float $ratio): self
{
$this->ratio = $ratio;
return $this;
}
Upvotes: 0
Reputation: 1234
Thanks to the comments, I think the question is not very clear/can be removed.
The serialization process is fine, it's the mapping from Doctrine which I did not get right.
It is totally OK, DECIMAL Doctrine/MySQL types are mapped to PHP strings. DECIMAL is designed to guarantee a precision for a numeric value. PHP's float type cannot guarantee the same precision.
Upvotes: 1