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
Requestobject 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.