11

I have an AngularJS form where I'm using ng-repeat to build the fields of the form dynamically based on another selection. I'm trying to generate the model name dynamically and am running into problems.

<div class="form-group" ng-repeat="parameter in apiParameters">
  <label for="{{parameter.paramName}}" class="col-sm-2 control-label">{{parameter.paramTitle}}</label>
  <div class="col-sm-3">
    <input type="text" class="form-control" name="{{parameter.paramName}}" id="{{parameter.paramName}}" ng-model="formData.parameters.{{parameter.paramName}}" placeholder="{{parameter.paramTitle}}">
  </div>
</div>

What I need is it to eval to something like ng-model="formData.parameters.fooId" or ng-model="formData.parameters.barId"

The above results in an error: Error: [$parse:syntax] Syntax Error: Token '{' is an unexpected token at column 21 of the expression [formData.parameters.{{parameter.paramName}}] starting at [{{parameter.paramName}}].

In my controller I have:

$scope.formData = {};
$scope.formData = {
  settings:
  {
    apiEndpoint: '',
    method: 'get'
  },
  parameters: {}
};

I've also tried ng-model="formData.parameters.[parameter.paramName]" (based on this question How can I set a dynamic model name in AngularJS?), but that doesn't eval and fails to set the ng-model value. I'm not sure if what I'm trying to accomplish is even possible. I'm assuming I need to go through the controller to achieve what I want, but any help would be appreciated.

Community
  • 1
  • 1
jdiver
  • 233
  • 1
  • 3
  • 10
  • Just a quick note: in your ng-repeat you reference apiParameters but only have parameters defined in your scope's formData. Also, a fiddle or plnkr would be helpful to work off of. – Brocco Mar 18 '14 at 19:59
  • I think you should consider writing a directive that has a isolated scope that allows you to pass in the object you'd like to modify. Also agree with Brocco a pnlkr is preferable to work through issues since ultimately can save to GitHub and use in the future for reference. – shaunhusain Mar 18 '14 at 20:00
  • Duly noted. I'll take the time to add a fiddle in the future and I'll keep the directive approach in mind. Thanks. – jdiver Mar 18 '14 at 21:10

2 Answers2

26

You just need to use hash key as model:

<div class="form-group" ng-repeat="parameter in apiParameters">
  <label for="{{parameter.paramName}}" class="col-sm-2 control-label">{{parameter.paramTitle}}</label>
  <div class="col-sm-3">
    <input type="text" class="form-control" name="{{parameter.paramName}}" id="{{parameter.paramName}}" ng-model="formData.parameters[parameter.paramName]" placeholder="{{parameter.paramTitle}}">
  </div>
</div>

There is many other approaches, but this one are simpler than others.

Sergey Moiseev
  • 2,953
  • 2
  • 24
  • 28
0

I have tested this solution but it has a problem for my self. The problem is that the parameter "formData" is assigned to each iteration individually. In the other words if you insert a pre tag in every iteration you will see the value of each iteration individually and you cannot get all the formData in your controller after submitting the form.

For this I have found a very simple solution and it is the ng-init !!!!

Simply add this code to your form and before your repetitive tag. For the example of this question we will have:

<form ng-init="formData = []">
    <div class="form-group" ng-repeat="parameter in apiParameters">
        <label for="{{parameter.paramName}}" class="col-sm-2 control-label">{{parameter.paramTitle}}</label>
        <div class="col-sm-3">
            <input type="text" class="form-control" name="{{parameter.paramName}}" id="{{parameter.paramName}}" ng-model="formData.parameters[parameter.paramName]" placeholder="{{parameter.paramTitle}}">
        </div>
    </div>
</form>