Take the 2-minute tour ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I am building an application with symfony2 on the backend. I am thinking about using AngularJS on the frontend, but I would still like to use symfony forms. I have setup the form with the correct modules and everything, but the problem occurs when the data is actually submitted.

Problem

When Symfony renders the form, it sets the inputs 'name' attribute to an array, like user[username], and this is the format that it expects to receive the data once it is submitted. I can't figure out how to get Angular to submit the data in this format. This is what I have:

<body ng-app="formApp" ng-controller="formController">
{{ form_start(form, {'attr':{'id': 'registerForm', 'ng-submit':'processForm()'}}) }}

{{ form_row(form.username, {'attr':{'ng-model':'formData.username'}}) }}
{{ form_row(form.password.first, {'attr':{'ng-model':'formData.password'}}) }}
{{ form_row(form.password.second) }}
{% for address in form.userAddresses %}
        {{ form_row(address.postalCode, {'attr':{'ng-model':'formData.postalCode'}}) }}
{% endfor %}

<div><input type="submit" value="Save" /></div>
{{ form_end(form) }}
</body>

and the controller:

function formController($scope, $http) {

$scope.formData = {};

$scope.processForm = function() {
    $http({
        method  : 'POST',
        url     : submit,
        data    : $.param($scope.formData), 
        headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
    })
        .success(function(data) {
            alert(data.message);
        });
};
}

When I submit, obviously the name-value pair uses the formData variables, so username=testuser instead of user[username]=testuser.

I tried to set the formData variable like formData.user[username], but that didn't work at all.

So is there a way to either use the inputs 'name' when submitting, or do something so that the form is submitted in the correct format? Any help would be great!

share|improve this question

4 Answers 4

up vote 1 down vote accepted

You can build the object symfony expects in a $scope function that you would bind to your form's submit with ng-click. So:

<input type="submit" value="Save" /></div>

would become

<input type="submit" value="Save" ng-click="submitForm()" /></div>

and in your controller you would add a function on the $scope object

$scope.submitForm = function() {
  var user = [];
  user['username'] = $scope.formData.username;
  //etc
};
share|improve this answer
    
thanks for this. I am confident that this will work, but do you know if there is a way that I can get the formatted array without having to manually define it for each form element? If there's no way to do it, I just need to know. –  Sehael Jan 18 '14 at 6:31
    
it turns out that this is the best solution I could find. I wish there was a cleaner way, but I can't find any. –  Sehael Jan 30 '14 at 17:32
2  
@akronymn How can this work: var user = []; user['username'] = $scope.formData.username;? user is an Array and you try to work with it as with Object –  Denis V Aug 2 '14 at 15:15

I think you should keep Angular form logic. You should use ng-model to bind data. To do this, you can create a Twig Form Theme to add ng-model attributes to your inputs, take a look at this gist.

Then you could pass input values to a $scope.data var in your controller like this:

$scope.var = {};

You should serialize data with the function provided in this article at line 109 or use jQuery.param() if you use jQuery.

Then create a submit method like this:

$scope.submit = function(){
    $http.post(
        'http://www.myurl.com',
        this.serializeData($scope.data),
        { headers: {
                'Content-Type': 'application/x-www-form-urlencoded' //Fix for Symfony
            }
        })
    .success(function(data) {
       //
    })
    .error(function (data){
        $log.error(data);
    });
}
share|improve this answer
1  
Good information to use application/x-www-form-urlencoded, however, if you are using the FOSRestBundle (recommended since you are separating concerns between the frontend and backend) you can use the body listener on the server side. –  Paul Redmond Oct 21 '14 at 7:20

You could use {'data-ng-model': 'formData["user[username]"]'}. To post formData you should pass it through jQuery.param().

share|improve this answer

I solve it using server side code. before handling of the request and validation i call the following function i created to change the format:

   /**
     * Format the request content with the form name
     * @param Request $request
     * @param $formName
     * @param null $content
     * @return Request
     */
     public function formatRequestWithForm(Request $request, $formName, $content = null)
     {
      if ($content === null) {
          $content = $request->getContent();
      }
      $contentArray = array($formName => json_decode($content, true));
      $request->attributes->add($contentArray);
      $request->request->add($contentArray);
      return $request;


     }  
share|improve this answer
    
Does this work for embedded forms? It seems to me like this will only work for simple forms. –  Sehael Jan 19 '14 at 4:19

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.