Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deserializing don't work #721

Closed
myfbone opened this issue Feb 16, 2019 · 8 comments
Closed

Deserializing don't work #721

myfbone opened this issue Feb 16, 2019 · 8 comments

Comments

@myfbone
Copy link

myfbone commented Feb 16, 2019

I have some trouble with deserializing array of my domain objects.

Here it is my domain object:

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use JMS\Serializer\Annotation\AccessType;
use JMS\Serializer\Annotation as JMS;

/**
 * @ORM\Entity(repositoryClass="App\Repository\BoxMeasureRepository")
 * @AccessType("public_method")
 */
class BoxMeasure
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     * @JMS\Exclude
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="App\Entity\Box", inversedBy="measures")
     * @ORM\JoinColumn(nullable=false)
     * @JMS\Exclude
     */
    private $box;

    /**
     * @ORM\Column(type="datetime")
     * @Assert\NotNull
     * @Assert\DateTime(format="d-m-Y H:i:s")
     * @JMS\Type("DateTime<'d-m-Y H:i:s'>")
     */
    private $measuredAt;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\Type("string")
     * @JMS\Type("string")
     */
    private $profile;

    /**
     * @ORM\Column(type="float", nullable=true)
     * @Assert\Type("float")
     * @JMS\Type("float")
     */
    private $temperature;

    /**
     * @ORM\Column(type="float", nullable=true)
     * @Assert\Type("float")
     * @JMS\Type("float")
     */
    private $humidity;

    /**
     * @ORM\Column(type="float", nullable=true)
     * @Assert\Type("float")
     * @JMS\Type("float")
     */
    private $dustConcentration;

    /**
     * @ORM\Column(type="float", nullable=true)
     * @Assert\Type("float")
     * @JMS\Type("float")
     */
    private $VOCConcentration;

    /**
     * @ORM\Column(type="float", nullable=true)
     * @Assert\Type("float")
     * @JMS\Type("float")
     */
    private $CO2Concentration;

    /**
     * @ORM\Column(type="float", nullable=true)
     * @Assert\Type("float")
     * @JMS\Type("float")
     */
    private $magneticRadiation;

    /**
     * @ORM\Column(type="float", nullable=true)
     * @Assert\Type("float")
     * @JMS\Type("float")
     */
    private $noiseLevel;

    /**
     * @ORM\Column(type="float", nullable=true)
     * @Assert\Type("float")
     * @JMS\Type("float")
     */
    private $lightLevel;

    /**
     * @ORM\Column(type="float", nullable=true)
     * @Assert\Type("float")
     * @JMS\Type("float")
     */
    private $lightRipple;

    /**
     * @ORM\Column(type="float", nullable=true)
     * @Assert\Type("float")
     * @JMS\Type("float")
     */
    private $vibration;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getBox(): ?Box
    {
        return $this->box;
    }

    public function setBox(?Box $box): self
    {
        $this->box = $box;

        return $this;
    }

    public function getMeasuredAt(): ?\DateTimeInterface
    {
        return $this->measuredAt;
    }

    public function setMeasuredAt(\DateTimeInterface $measuredAt): self
    {
        $this->measuredAt = $measuredAt;

        return $this;
    }

    public function getProfile(): ?string
    {
        return $this->profile;
    }

    public function setProfile(string $profile): self
    {
        $this->profile = $profile;

        return $this;
    }

    public function getTemperature(): ?float
    {
        return $this->temperature;
    }

    public function setTemperature(?float $temperature): self
    {
        $this->temperature = $temperature;

        return $this;
    }

    public function getHumidity(): ?float
    {
        return $this->humidity;
    }

    public function setHumidity(?float $humidity): self
    {
        $this->humidity = $humidity;

        return $this;
    }

    public function getDustConcentration(): ?float
    {
        return $this->dustConcentration;
    }

    public function setDustConcentration(?float $dustConcentration): self
    {
        $this->dustConcentration = $dustConcentration;

        return $this;
    }

    public function getVOCConcentration(): ?float
    {
        return $this->VOCConcentration;
    }

    public function setVOCConcentration(?float $VOCConcentration): self
    {
        $this->VOCConcentration = $VOCConcentration;

        return $this;
    }

    public function getCO2Concentration(): ?float
    {
        return $this->CO2Concentration;
    }

    public function setCO2Concentration(?float $CO2Concentration): self
    {
        $this->CO2Concentration = $CO2Concentration;

        return $this;
    }

    public function getMagneticRadiation(): ?float
    {
        return $this->magneticRadiation;
    }

    public function setMagneticRadiation(?float $magneticRadiation): self
    {
        $this->magneticRadiation = $magneticRadiation;

        return $this;
    }

    public function getNoiseLevel(): ?float
    {
        return $this->noiseLevel;
    }

    public function setNoiseLevel(?float $noiseLevel): self
    {
        $this->noiseLevel = $noiseLevel;

        return $this;
    }

    public function getLightLevel(): ?float
    {
        return $this->lightLevel;
    }

    public function setLightLevel(?float $lightLevel): self
    {
        $this->lightLevel = $lightLevel;

        return $this;
    }

    public function getLightRipple(): ?float
    {
        return $this->lightRipple;
    }

    public function setLightRipple(?float $lightRipple): self
    {
        $this->lightRipple = $lightRipple;

        return $this;
    }

    public function getVibration(): ?float
    {
        return $this->vibration;
    }

    public function setVibration(?float $vibration): self
    {
        $this->vibration = $vibration;

        return $this;
    }
}

My controller method:

public function persistMeasures(Request $request, ValidatorInterface $validator){
        if(!$request->getContent())
            return JsonResponse(['code' => 400, 'message' => 'Please provide request body.']);
        $serializer = SerializerBuilder::create()->build();
        $des_data = $serializer->deserialize($request->getContent(), 'array<App\Entity\BoxMeasure>', 'json');
        
        $errors = $this->validateMeasures($des_data, $validator);

//Added for debug
        return new JsonResponse($des_data);

        if($errors){
            return new JsonResponse(['code' => 400, 'message' => 'validation failed', 'errors' => (string) $errors]);
        }

        $box = $request->getUser();
        if(!($box instanceof Box))
            return new JsonResponse(['code' => 400, 'message' => 'You have to assess this route as Box.']);
        $this->saveMeasures($des_data, $box);

        return new JsonResponse(['code' => 200, 'message' => 'measures successfully persisted']);
    }

And it is my request JSON:

[
	{
		"measuredAt":"16-02-2019 18:15:45",
		"profile":"home",
		"temperature":20.3,
		"humidity":100.45,
		"dustConcentration":13.6432,
		"VOCConcentration":56543.322,
		"CO2Concentration":235.63,
		"magneticRadiation":1.0021,
		"noiseLevel":11,
		"lightLevel":991.21,
		"lightRipple":1140,
		"vibration":19.2
	},
	{
		"measuredAt":"16-02-2019 18:16:00",
		"profile":"home",
		"temperature":20.3,
		"humidity":130.45,
		"dustConcentration":13.6432,
		"VOCConcentration":55543.322,
		"CO2Concentration":236.63,
		"magneticRadiation":1.0021,
		"noiseLevel":13.1,
		"lightLevel":921.21,
		"lightRipple":1140,
		"vibration":19.2
	},
	{
		"measuredAt":"16-02-2019 18:16:15",
		"profile":"home",
		"temperature":21.3,
		"humidity":132.45,
		"dustConcentration":12.432,
		"VOCConcentration":55543.322,
		"CO2Concentration":236.63,
		"magneticRadiation":1.0021,
		"noiseLevel":14.1,
		"lightLevel":921.21,
		"lightRipple":1142,
		"vibration":19.3
	}
]

Response:

[
    {},
    {},
    {}
]

I totally don't understand what I am doing wrong. Please help me

@goetas
Copy link
Collaborator

goetas commented Feb 16, 2019

$serializer = SerializerBuilder::create()->build();... why not use the symfony bundle for it?

I think you have just misconfigured something.

@myfbone
Copy link
Author

myfbone commented Feb 16, 2019

$serializer = SerializerBuilder::create()->build();... why not use the symfony bundle for it?

I think you have just misconfigured something.

Actually I don't know. I saw one question on stackoverflow about deserialization and there was recommended to use JMSSerializer :)

@goetas
Copy link
Collaborator

goetas commented Feb 16, 2019

I mean, you created a ticket on the JMSSerializerBundle, but you are not using the bundle.
And most probably you problem will be solved by using the bundle..

@myfbone
Copy link
Author

myfbone commented Feb 16, 2019

I mean, you created a ticket on the JMSSerializerBundle, but you are not using the bundle.
And most probably you problem will be solved by using the bundle..

But I think that I use this Bundle. Here it is my use string:
use JMS\Serializer\SerializerBuilder;

@myfbone
Copy link
Author

myfbone commented Feb 16, 2019

<?php

namespace App\Controller\Box;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use App\Entity\BoxMeasure;
use App\Entity\Box;
use Symfony\Component\Validator\Validator\ValidatorInterface;
use Doctrine\ORM\EntityManagerInterface;

class BoxController extends AbstractController
{
    protected $entityManager;

    public function __construct(EntityManagerInterface $entityManager){
        $this->entityManager = $entityManager;
    }

    /**
     * @Route("/api/box/measures",
     * methods={"POST"},
     * name="persist_measures",
     * requirements={
     *         "_format": "json"
     *     })
     */
    public function persistMeasures(Request $request, ValidatorInterface $validator, \JMS\Serializer\SerializerInterface $serializer){
        if(!$request->getContent())
            return JsonResponse(['code' => 400, 'message' => 'Please provide request body.']);
        $des_data = $serializer->deserialize($request->getContent(), 'array<App\Entity\BoxMeasure>', 'json');
        
        $errors = $this->validateMeasures($des_data, $validator);

        return new JsonResponse($des_data);

        if($errors){
            return new JsonResponse(['code' => 400, 'message' => 'validation failed', 'errors' => (string) $errors]);
        }

        $box = $request->getUser();
        if(!($box instanceof Box))
            return new JsonResponse(['code' => 400, 'message' => 'You have to assess this route as Box.']);
        $this->saveMeasures($des_data, $box);

        return new JsonResponse(['code' => 200, 'message' => 'measures successfully persisted']);
    }

    private function validateMeasures($data, ValidatorInterface $validator){
        foreach($data as $boxMeasure){
            $errors = $validator->validate($boxMeasure);
            if(count($errors) > 0)
                return $errors;
        }
    }
    
    private function saveMeasures($data, Box $box){
        foreach($data as $boxMeasure){
            $boxMeasure->setBox($box);
            $this->entityManager->persist($boxMeasure);
        }
        $this->entityManager->flush();
    }

    /**
     * @Route("/api/box/test", methods={"POST"}, name="test")
     */
    public function boxTest(Request $request){
        $serializer = SerializerBuilder::create()->build();
        //$data = $serializer->deserialize($request->getContent());
        $data = json_decode($request->getContent(),true);
        return new JsonResponse(["data"=>$data['data']['a']]);
    }
}

@goetas
Copy link
Collaborator

goetas commented Feb 16, 2019

So, same result or it worked? Your last comment had only code but no text

@myfbone
Copy link
Author

myfbone commented Feb 16, 2019

I realised that it shows empty objects because it doesn't serializes. I missed it because I used to use laravel and it can serialize entities out of the box. Also there was a problem with cases. Deserializer require snake case but I used camel case. So I solved the problem

@goetas goetas closed this as completed Feb 16, 2019
@goetas
Copy link
Collaborator

goetas commented Feb 16, 2019

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants