I enjoy being a PHP Developer. PHP is a very flexible language and Symfony2 is a modern framework that forces many SOLID habits on developers. I also enjoy working with AngularJS. AngularJS makes Javascript fun and much easier to work with. Moreover, much like Symfony2, it forces good habits on developers. Getting the two to work together, however, can be a little bit of a chore if not careful.
The Problem
For starters, when the AngularJS $http
service POSTs data the header
application/x-www-form-urlencoded
is never set (unlike jQuery’s $.ajax()
).
Also, the $http
data is not serialized when sent. Both of these
facts mean that the $_POST
variable is never set properly by php. Without
the $_POST
variable
Symfony’s built in form
handling
cannot be used.
It should be noted that Symfony’s
Request
object allows for access to raw post content via thegetContent()
method; meaning POST data can be processed manually if needed.
When creating a FormType in Symfony, a name is required. By default that name
will be called something like bundle_path_entityname
, and all post content
will need to be in a multidimensional array with the FormType name as the key.
This means that the posted data we send with Angular will need to follow this
standard.
Consider shortening the FormType name into something more meaningful.
The Fix
The fix is actually pretty simple:
- angular needs to forced into setting a header
- the data needs to be serialized
- and the data needs to be normalized into a multidimensional array.
On all $http
requests we can set a headers
object. That means that the
Content-Type header can be set on the $http
request.
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
To serialize the data being sent, jQuery works well. Just use
$.param()
on the data and be done with
it.
data: $.param({
postData
})
Normalizing the data into a proper serialized string is as simple as creating a javascript object. Remember that the FormType name needs to be the key or parent attribute on the object.
var postData = {
formtype_name: {
id: some_id,
name: some_name
}
}
Putting it all together, the javascript should look something like this:
var postData = {
formtype_name: {
id: some_id,
name: some_name
}
};
$http({
method: "POST",
url: url,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: $.param(postData)
});
Doing all this work on the frontend will allow for use of the normal form processing built into Symfony.