1

I am new to angular when I was trying to put the form validation to the text field form was present inside *ngFor loop, So validation is working but it shows to every field but I want validation the particular field only , so please help me How to put the validation to the particular form field.

**HTML** 

    <div class="container" *ngFor="let post of posts; let i = index">
    <div class="row">
            <div class="col-md-12" style="display: block; ">

              <form [formGroup]="commentForm" method="post" enctype="multipart/form-data" (ngSubmit)="comment_Submit(post.user_id, post.post_id,
                commentForm)">
                <div class="form-group">
                  <input type="text" class="form-control" name="comment{{i}}" formControlName="comment" id="comment"
                    placeholder="Enter comments" cols="40" rows="5" spellcheck="true"
                    style="width:100%; height: auto; border: 1px solid #ada5a5; border-radius: 4px; outline: none; user-select: text; white-space: pre-wrap; overflow-wrap: break-word; "
                    [ngClass]="{'form-control': true,
                  'is-invalid': !f.comment.valid,
                  'is-valid':f.comment.valid}">
                  <div *ngIf="f.comment.errors?.minlength && f.comment.touched" class="text-danger">Comment
                    should be at
                    least 2 characters.</div>
                </div>

                <button type="submit" class="btn-sm btn-success" [disabled]="!commentForm.valid">Comment</button>

              </form>
            </div>
          </div>
    </div>

**TypeScript**
export class PostsComponent implements OnInit {

get f() { return this.commentForm.controls; }

constructor(private userService: UserService, private formBuilder: FormBuilder,
    private alerts: AlertsService) {
   this.commentFormValidation();

  }

commentForm: FormGroup;
  ngOnInit() {   }

    commentFormValidation() {
     this.commentForm = this.formBuilder.group({
      comment: [null, [Validators.required, Validators.minLength(2)]]
    });
  }
Sivasankar chimata
  • 311
  • 1
  • 16
  • 31
  • create stackblitz and share to help you on this. And You can solve such case using FormArray – programoholic Feb 15 '19 at 10:28
  • to check if is valid "comment, you must use: commentForm.controls.coment.valid, anyway, Angular add class for you when is invalid a field, see https://angular.io/guide/form-validation#control-status-css-classes – Eliseo Feb 15 '19 at 11:48
  • Thank you for your reply, but i am looking for the iteration of form validation inside *ngFor loop – Sivasankar chimata Feb 15 '19 at 12:18
  • What you want is `FormArray`. That just looks kinda weird. You would want to put the `posts` array **inside** the formgroup, instead of trying to iterate your array and stick a form for each. – AT82 Feb 15 '19 at 13:35
  • Check my answer here, it should help you: https://stackoverflow.com/a/42975138/6294072 – AT82 Feb 15 '19 at 13:41
  • I can't put post array in the form because , i am using the form for writing comment for my posts , for every post there is a comment box below the post description , for the comment box i am putting the validation, validation working correctly but when it got error it shows for every comment field So i need solution for that .Help me in this using i="index" . – Sivasankar chimata Feb 15 '19 at 14:13

1 Answers1

0

Your posts all share the one and same form. If you have n amount of posts, you need n amount of forms. We can achieve this by creating an array (just a JS array) of formgroups, the same length that your posts array is...

formsArr = [];

constructor(private fb: FormBuilder) { }

ngOnInit() {
  this.posts.forEach((x) => {
    this.formsArr.push(this.fb.group({
      comment: this.fb.control('', [Validators.required, Validators.minLength(2)])
    }))
  })
}

Then in your template you iterate formsArr. You probably need access to some stuff in your posts array... so we add the index in iteration, therefore you can access the specific post with posts[i]. Also remove method="post" from your form:

<div *ngFor="let a of formsArr; let i = index">
  <form [formGroup]="a" (ngSubmit)="onSubmit(a.value, posts[i].user_id)">
    <input formControlName="comment" />
    <small *ngIf="a.hasError('minlength', 'comment') && a.get('comment').touched">
      Needs to be 2 letters
    </small>
    <button type="submit" [disabled]="!a.valid">Comment</button>
  </form>
</div>

StackBlitz

AT82
  • 71,416
  • 24
  • 140
  • 167
  • Sir once check my TypeScript code My github link https://github.com/sivasankarchimata/Angular-Node.js-MySQL-social-networking-site-/tree/master/git – Sivasankar chimata Feb 16 '19 at 06:53
  • getting error like this when i am using this.posts array from database , ProfileComponent.html:54 ERROR TypeError: Cannot read property 'forEach' of undefined at PostsComponent.push../src/app/user/posts/posts.component.ts.PostsComponent.ngOnInit (posts.component.ts:70) at checkAndUpdateDirectiveInline (core.js:9250) at checkAndUpdateNodeInline (core.js:10514) at checkAndUpdateNode (core.js:10476) – Sivasankar chimata Feb 16 '19 at 08:25
  • well apparently `this.posts` is `undefined`. You need to do the iteration inside the subscribe callback, as a http-request is asynchronous: https://stackoverflow.com/questions/43055706/how-do-i-return-the-response-from-an-observable-http-async-call-in-angular2 – AT82 Feb 16 '19 at 11:54
  • I don't understand what you mean. If you are having issues with your code, please fork my stackblitz and reproduce the issue. The above is a demo, just showing how you should do it. If your posts is coming in asynchronously, you need to execute the above code **when** posts actually have value. – AT82 Feb 16 '19 at 14:36
  • https://github.com/sivasankarchimata/Angular-Node.js-MySQL-social-networking-site-/tree/master/git this is my github link for the source files – Sivasankar chimata Feb 16 '19 at 15:29
  • So like I guessed, getting posts is asynchronous. Iterate the post *when you have data* I've told you many times and even linked you a question on how asynxhronozity works ;) – AT82 Feb 16 '19 at 16:26