0
votes

I am trying to do a PUT request on an entity, from an angular 5 client to API Platform.

On the angular side, I retrieve an address via Google maps. This address is a property of an Entity JourneyAddress, so I send a PUT request to API Platform with my JourneyAddress model, with an address property which is an array of google map address components (street_address, locality, etc.).

Now I need to perform some operations on this property before submitting it to Doctrine, ie I need to match the locality given by google with a Locality in our Database.

I was thinking about a listener which would listen for JourneyAddress prePersist and preUpdate events, find the locality instance I need with something like LocalityRepository::findBy(['name' => 'Paris']), update the journeyAddress instance and give it back to Doctrine to perform persist/update operations.

The problem is that API Platform checks if the type of the data submitted corresponds to what Doctrine expects. I sent API Platform an array, but Doctrine actually expects a string.

For context, the array sent could be :

src/Doctrine/EventListener/JourneyAddressListener.php:32:
object(App\Entity\JourneyAddress)[2615]
  private 'id' => null
  private 'title' => string 'dzfkdqsmlfjsldkflm' (length=18)
  private 'search' => string 'mlsqjfkldsjfsqdjlmf' (length=19)
  private 'address' => 
    array (size=8)
      'street_number' => string '2650' (length=4)
      'route' => string 'Avenida Rivadavia' (length=17)
      'sublocality_level_1' => string 'Balvanera' (length=9)
      'administrative_area_level_2' => string 'Comuna 3' (length=8)
  'administrative_area_level_1' => string 'Buenos Aires' (length=12)
      'country' => string 'Argentine' (length=9)
      'postal_code' => string 'C1034' (length=5)
      'postal_code_suffix' => string 'ACS' (length=3)
  private 'latitude' => float 50.6507791
  private 'longitude' => float 3.0657951
  private 'media' => null
  private 'indication' => string 'klqsjflkmqjfkqjfksflmlqfmlks' (length=28)

I need to extract the street_address and save it as the address property of my JourneyAddress, but the Doctrine entity is :

/**
 * @ORM\Column(type="string", length=255)
 * @Groups("journey")
 * @Assert\Type("string")
 * @Assert\NotBlank(
 *        message = "Le champs 'Adresse du point de départ' doit être rempli",
 *        groups={"departureFormValidation"}
 * )
 */
private $address;

Is there a way that my listener will be used before actual API Platform type-checking ? I also tried to do a custom operation but the result was the same, type-checking always comes first and prevents any further action.

I could of course replace the type of address by array and then send ['my string'], but I feed it should not be that way.

1

1 Answers

1
votes

Doctrine listeners are always executed after validation. There are built in api-platform (Symfony) event listeners that are executed before validation: https://api-platform.com/docs/core/events/ PRE_VALIDATE seems like a good place for this.

However, having mixed data type (array, string) for the same field is not a good idea, consider using a separate model class for your array address or a separate unmapped field.