0

Clicking on the button to Add a URL with the FormArray class is submiting the entire form, thus not letting the user enter multiple URLs without submitting a new entry to the database every time he clicks on the button.

This seemed to me like it was an event bubbling issue but using $event.stopPropagation didn't change the behavior at all.

app.component.html

<div class="flex-container">
  <form [formGroup]="form" (ngSubmit)="submit()" class="card">
    <div class="form-group">
      <label for="">Title</label>
      <input 
        type="text"
        formControlName="title"
        class="form-control"
      />
    </div>
    <div class="form-group">
      <label for="">Image URLs</label>
      <input
        type="text"
        class="form-control"
        #url
      >
      <button (click)="addUrl(url, $event)">Add a URL</button>
      <ul>
        <li *ngFor="let url of imageUrls.controls" class="form-control" style="color: black;">
          {{ url.value }}
        </li>
      </ul>
    </div>
    <div class="form-group">
      <label for="">Description</label>
      <textarea
        formControlName="description"
        class="form-control"
      >
      </textarea>
    </div>
    <button class="btn btn-primary" type="submit">Submit</button>
  </form>
</div>

app.component.ts

import { Component, OnInit } from '@angular/core';
import { Subscription, Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { AngularFireDatabase } from '@angular/fire/database';
import { AngularFireList, AngularFireObject  } from 'angularfire2/database';
import { AngularFirestore } from '@angular/fire/firestore';
import { FormGroup, FormArray, FormControl, FormBuilder, Validators, AbstractControl } from '@angular/forms';
import { Router } from "@angular/router";

@Component({
  selector: 'app-component',
  templateUrl: './app-component.component.html',
  styleUrls: ['./app-component.component.css']
})

export class GalleryAdminComponent {

  form: FormGroup;

  constructor(fb: FormBuilder, private router: Router) {

    this.form = fb.group({
      title: [''],
      description: [''],
      imageUrls: fb.array([])
    });
  }

  get title() {
    return this.form.get('title');
  }

  get description() {
    return this.form.get('description');
  }

  get imageUrls() {
    return this.form.get('imageUrls') as FormArray;
  }

  addUrl(url: HTMLInputElement, $event) {
    $event.stopPropagation(); //doesn't work, clicking the add url button still submits the entire form
    (this.imageUrls as FormArray).push(new FormControl(url.value));
    url.value = '';
  }

  addEvent(input: any) {
    const itemsRef = this.db.list('events');
    itemsRef.push(input);
  }

  submit() {
    console.log("this.form", this.form);
    console.log("this.form.value", this.form.value);
    this.addEvent(this.form.value);
    this.router.navigate(['/gallery']);
  }

}

I want to use FormArray in such a way that the FormControl objects for imageUrls can be dynamically added one at a time. This would then have the user fill out the form, add zero or more imageUrl strings AND THEN click on the submit button to send the form.value object literal to the server.

2 Answers 2

3

Just add type property of a button.

  <button type="button" (click)="addUrl(url, $event)">Add a URL</button>

This won't let your form submit when you click on Add a URL button.

Reason why this is happening:

The default value for the type attribute of a button is "submit". Click here to see more.

So Set it to type="button" to produce a button that doesn't submit the form.

Sign up to request clarification or add additional context in comments.

1 Comment

@RayGar, I have added the reason. Please check it.
-1

const formArrayName = controle.get('multiExpenseArray') as FormArray;

1 Comment

What does that do? Where do you add it? Why does it work? In the current state this a pretty low quality answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.