0
votes

In our Angular form (we are using template driven forms) we have a list of input fields which are rendered dynamically, as so, we need to validate then. Following this: Using template driven form with dynamic input list (ngFor) I didn't come any further as it seems to be outdated, as the plunkr sample is not working.

that is our tbody which renders our list:

  <tbody>
    <tr *ngFor="let item of items; let i=index">
      <td><span>{{ item.categoryName }}</span></td>
      <td class="text-right">
        <input *ngIf="editMode" 
          type="number" 
          tabindex="1" 
          autocomplete="off" 
          [(ngModel)]="item.value" name="value-{{item.categoryId}}" #value="ngModel"
          required 
        />
        {{value.valid}} <!--As I'm using ngForm I was expecting to receive false or true here-->
        <span *ngIf="!editMode">{{ item.value }}</span>
      </td>
      <td>
        <app-status [status]="item.status"></app-status>
      </td>
    </tr>
  </tbody>

This works fine, the list can be seen, but the validation does not work.

if I try: {{value.valid}} I get the following error:

ERROR TypeError: Cannot read property 'valid' of undefined

Means, my instance of ngModel did't work.

What am I missing?

1
The problem here may be the template reference variable. You have the same template reference variable on each input box. According to the documentation: The scope of a reference variable is the entire template. Do not define the same variable name more than once in the same template. The runtime value will be unpredictable. from: angular.io/guide/… - DeborahK
I didn't get your point - DAG
for each input box, you are defining a value variable, but the scope of that variable is not isolated to the input box, it's able to be referenced by the whole scope of the template. So especially where you're looping through and creating these separately in your template, it's possible that something gets messed up along the way, hence the warning: - SaxyPandaBear
#value is a template reference variable. You are adding a template reference variable with this same name to every input box. According to the documentation, you should not use the same template reference variable more than once in a template. - DeborahK
what is the solution if I have an iteration? create a scoped function that validates my vaule for me? then there is no need of the required attribute? - DAG

1 Answers

0
votes

Where are you trying to do {{value.valid}}? I don't see that here so I don't know what would be causing a null definition of value.

Rather than using an attribute of value, you could have a function in your component that does the validation check for you.

<tr *ngFor="let item of items; let i = index">
  <!-- somewhere in your code -->
  <div *ngIf="myValidationFunction(value)">
    <!-- stuff -->
  </div> 

Then in your ts file, you could have something that does a check on it. If it is always required, it's pretty simple to do.

myValidationFunction(value) {
    if (value) {
        // results to 'true' if value isn't null
        return value.valid; // where valid is some field in value
    }
    else { // if value is null, you can say that it is wrong
        return false; // this means that it will not be valid until it's defined
    }