简体   繁体   中英

Angular *ngFor loop breaks after two iterations and I am getting “form submission canceled because form is not connected” in the console

I have a for loop that iterates through an array of 18 objects. I also have a function in the for loop that only shows one object at a time but it is breaking after 2 iterations. With each iteration I am getting "Form submission canceled because the form is not connected" even though the form is being submitted in the first two iterations before it breaks. Here is a video to visualize: https://youtu.be/RnUki_-q_bk

The issue is with the showSubItem(ind)function I'm assuming. My component.ts file:

import { Component, OnInit } from "@angular/core";
declare var jQuery: any;

@Component({
  selector: "app-home",
  templateUrl: "./home.component.html",
  styleUrls: ["./home.component.scss"],
})
export class HomeComponent implements OnInit {

  cards = [
    {
      description: "Do you have a monthly student loan payment?",
    },
    {
      description: "Do you have a monthly car loan payment?",
    },
    {
      description: "Do you have a monthly car insurance payment?",
    },
    {
      description:
        "How much do you estimate you spend on gas for your car monthly?",
    },
    {
      description:
        "How much do you estimate you spend on average, for car maintenance/repair per month?",
    },
    {
      description:
        "Do you have any monthly health/dental expenses(including health insurance, medical bills, prescription drugs) ?",
    },
    {
      description:
        "How much do you estimate you spend on groceries and essential supplies per month",
    },
    {
      description: "Do you pay for a monthly fitness membership?",
    },
    {
      description: "Do you pay for any monthly streaming services?",
    },
    {
      description: "Do you pay for a monthly phone bill?",
    },
    {
      description:
        "How much do you estimate you spend on dining out per month?",
    },
    {
      description: "Estimated monthly cost for reacreation and entertainment?",
    },
    {
      description: "Do you pay for child care or child support?",
    },
    {
      description:
        "Any other monthly expenses that weren't accounted for please add them here(other than rent, electricity, and internet/cable).",
    },
    {
      description: "What is your total household monthly income after taxes?",
    },
    {
      description:
        "Do you recieve any other monthly benefits(social security benefits, disability income, etc) ?",
    },
    {
      description: "Do you have any other sources of perpetual monthly income?",
    },
    {
      description:
        "How much money do you have saved that you can put towards a downpayment on a house?",
    },
  ];
  numbersInForm: any = {};
  hideme = [];
  allNumbs: any = [];
  newObj = {};
  newArry: any = [];
  mortgageRateFound: any;
  calculate: any;
  finalAnswer: number;
  expenses: any;
  leftSide: number;
  rightSide: number;
  isNaN: Function = Number.isNaN;
  monthlyPayment: number;
  formula: number;
  brackets: number;
  house: any;
  currentValue: any;
  downPayment: any;
  income: any;
  mortgage: any;
  newString: string = "";
  
  visibleIndex:number = 0;


  constructor() {}

  ngOnInit() {
    (function ($) {
      $(document).ready(function () {
        $("button").click(function () {
          $("#jumbo, #fadeButton").hide(200, "linear");
          $("form").show(200, "linear");
        });
      });
    })(jQuery);
  }

  getClicked() {
    this.newObj = {};
    const newObj = Object.assign(
      {},
      ...Object.values(this.numbersInForm).map((v, i) => ({ [i + 1]: v }))
    );
    let allNumbs = Object.values(newObj);
    console.log(allNumbs);
    this.downPayment = allNumbs[allNumbs.length - 1];
    this.calculate = 0;
    this.house = 0;
    this.expenses = allNumbs[0];
    this.income = allNumbs[14];
    if ((allNumbs.length = 18)) {
      for (var j = 1; j <= 16; j++) {
        if (j < 14) {
          this.expenses += allNumbs[j];
        }
        if (j >= 15) {
          this.income += allNumbs[j];
        }
        this.calculate = this.income - this.expenses;
      }
    }
    console.log("expenses",this.expenses);
    console.log("income", this.income);
    console.log("income-expenses", this.calculate);
    console.log("downpayment", this.downPayment);
    this.calculateHouse()
  }

  showSubItem(ind) { 
    this.getClicked();  
    if (this.visibleIndex === ind) {
      this.visibleIndex += 1;
      console.log(this.visibleIndex)
    } else {
      this.visibleIndex = ind;
      this.visibleIndex += 1;
    }
  }

  calculateHouse() {
    console.log("made it to calculate house");
    this.mortgageRateFound = 0.0025;
    this.leftSide = Math.pow(1 + this.mortgageRateFound, 360);
    this.rightSide = Math.pow(1 + this.mortgageRateFound, 360) - 1;
    console.log("leftside", this.leftSide)
    console.log("rightside", this.rightSide)
    this.brackets = (this.mortgageRateFound * this.leftSide) / (this.rightSide);
    this.formula = this.calculate / this.brackets + this.downPayment;
    this.finalAnswer = Math.trunc(this.formula)
    console.log("brackets", this.brackets);
    console.log("formula", this.formula);
    console.log("finalanswer", this.finalAnswer);
  }
}

The *ngFor in my HTML file:

    <div class="formDiv" *ngFor="let card of cards; let i = index">
      <div *ngIf="visibleIndex === i">
        <form #myForm="ngForm" #checkForm="ngForm" (ngSubmit)="getClicked(checkForm)" class="login-container">
          <div class="count" id="_count">
            <h3>{{ i + 1 }}/18</h3>
          </div>

          <label>
            <h1 class="description">{{ card.description }}</h1>
          </label>
          <label id="inputField"><i id="dollar" class="fas fa-dollar-sign"></i><i id="dollar"
              class="fas fa-dollar-sign"></i><i id="dollar" class="fas fa-dollar-sign"></i><input type="number"
              name="numbersInForm[card.description]" [(ngModel)]="numbersInForm[card.description]" id="input"
              class="form-input" placeholder="Ex: $100 or $0 if none" /></label>

          <button (click)="showSubItem(i)" type="button" type="submit">
            Next
          </button>
        </form>
      </div>
    </div>

Apparently you should not put the form inside of the ngFor. Because they will have the same name in a single template.

If you really want to have multiple forms in ngFor, you can extract the form section into a separate component, something like:

<div class="formDiv" *ngFor="let card of cards; let i = index">
  <div *ngIf="visibleIndex === i">
    <custom-form-component [card]="card"></custom-form-component>
  </div>
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM