Injecting live data into an input field within a table using Angular 4

Trying to create a dynamic row table with input fields in all cells. The loaded data is static, and I'm facing issues adding more data in the view. However, the functionality to add and delete rows is working fine. I have experimented with ngModel and value but couldn't get it to work.

app.component.html:

    <table>
            <thead>
                <button (click)="onAddRow()" *ngIf="addForm.get('rows')">add row</button>
            </thead>
            <tbody>
                <tr *ngFor="let row of addForm.get('rows')?.controls; let index = index;">
          <td>
            name : <input  [formControl]="row.get('name')">
          </td>
          <td>
            description : <input [formControl]="row.get('description')">
          </td>
          <td>
            qty : <input [formControl]="row.get('qty')">
          </td>
          <td>
            <button (click)="onRemoveRow(index)">Remove</button>
          </td>
                </tr>
            </tbody>
        </table>

app.component.ts:

import { Component } from '@angular/core';
import { FormGroup, FormBuilder, Validators, FormControl, FormArray, NgForm } from '@angular/forms'

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  addForm: FormGroup;
  rows: FormArray;

  constructor(private fb: FormBuilder) {
    this.addForm = this.fb.group({
      items: [null, Validators.required],
      items_value: ['no', Validators.required]
    });
    this.rows = this.fb.array([{
    "name": "Test Item",
    "description": "Dedsc",
    "qty": "q23"
  }]);

  }

  ngOnInit() {
    this.addForm.get("items").valueChanges.subscribe(val => {
      if (val === true) {
        this.addForm.get("items_value").setValue("yes");

        this.addForm.addControl('rows', this.rows);
      }
      if (val === false) {
        this.addForm.get("items_value").setValue("no");
        this.addForm.removeControl('rows');
      }
    });
  }

  onAddRow() {
    this.rows.push(this.createItemFormGroup());
  }

  onRemoveRow(rowIndex:number){
    this.rows.removeAt(rowIndex);
  }

  createItemFormGroup(): FormGroup {
    return this.fb.group({
      name: null,
      description: null,
      qty: null
    });
  }

}

My output: https://i.sstatic.net/Kt54S.png

Expected output: https://i.sstatic.net/ODqVy.png

Also sharing a Stackblitz Example for reference.

Answer №1

Using [ngModel] is not necessary when working with reactive forms. The reason these inputs appear empty is because each item form group was created with null values. If you have data that should be preloaded, make sure to pass it as the initial value for each control within the createItemFormGroup method, or update the value using the setValue/patchValue methods of the form array or appropriate form group.

Answer №2

It may not be exactly what you're looking for, but take a look at this: https://stackblitz.com/edit/dynamically-add-rows-k2lbkw

  • I made some adjustments to the code by replacing formControl with formControlName. Pay attention to the value property.
<td>
     Name: <input  formControlName="name" 
                   [ngModel]="row.get('name').value" >
</td>
  • I also included name, description, and qty in the form builder object.
    constructor(private fb: FormBuilder) {
        this.addForm = this.fb.group({
          items: [null, Validators.required],
          items_value: ['no', Validators.required],
          name: [null, Validators.required],
          description: [null, Validators.required],
          qty: [null, Validators.required]
        });
        this.rows = this.fb.array([]);
      }
  • Additionally, I added dummy values within the createItemFormGroup method.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to manage your javascript variables

Here is the code snippet I am working with: var json = jQuery.parseJSON(data); console.log(json) When I run this code, the output looks like this: Object {sql: "SELECT venta.cliente_tipodoc,count(*) AS cantidad FROM venta venta", results: Array[1], ...

Tips for Enhancing Window Leveling (Brightness and Contrast)

const pixelArray = [11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11,11..] if (pixelArray != null) { for (let i = 0; i < pixelArray.length; i++) { let ...

Running pug directly from the local node_modules directory

I'm currently attempting to run pug (/jade) from my node_modules directory, however I am unable to locate the executable within the node_modules/.bin folder. I am running MacOS 10.12.5 and installed pug using the "npm install --save pug" command. Is ...

Extract specific elements from an array using Mongoose's $slice operator while still maintaining the

Currently, my task is to retrieve the total number of items in my News object and return a portion of those items as objects. While I have successfully implemented the $slice operator in my query, I am struggling to determine the original array size of the ...

Error in JSON parsing: The key 'item' does not have a corresponding value

After making some adjustments to the JSON response, I encountered a new error message W/System.err: org.json.JSONException: No value for retCode. The complete error: 04-03 12:53:26.624 14366-14366/com.allianz.azemployee W/System.err: org.json.JSONExc ...

What could be causing my for loop to become unresponsive?

My for loop seems to be populating all fields with the last object parsed. http://codepen.io/anon/pen/EKxNaN This is my current code. I created something similar on CodePen since I can't access JSON from the original source there. var championMaste ...

Fixing extended properties on an express request can be done by following these steps

I've been working on a JavaScript middleware where I can extract user information using the "req" object in the route handler. When I log currentUser, I get the expected value, but I'm encountering a TypeScript error warning: Property 'curre ...

Problem with dynamic page routes in Next.js (and using TypeScript)

Hi everyone, I'm currently learning next.js and I'm facing an issue while trying to set up a route like **pages/perfil/[name]** The problem I'm encountering is that the data fetched from an API call for this page is based on an id, but I wa ...

Develop a fresh class by inheriting from HTMLDivElement and expanding its prototype

My goal is to add a new method to the HTMLDivElement prototype without cluttering the HTMLDivElement itself with my custom methods. This has led me to attempt creating a new class that extends the HTMLDivElement. export class ScrollableElement extends HTML ...

Easily choose multiple items at once by searching with react-select

I have implemented react-select to showcase a searchable drop-down list of items where users can select multiple items. The list is lengthy, and users often find it tedious to multi-select many items that match the same filter string. This is because each ...

JSON backward compatibility ensures that newer versions of software can still support

I have been utilizing a Java application that saves the fields of an object to a file and can load them at a later time. Previously, I used a customized version of java.util.properties.Properties file where properties were written in the order they were a ...

Unusual occurrences when making several ajax requests to a single URL

I've encountered a peculiar scenario while working on a CherryPy server, and I'm seeking assistance in understanding the intricacies behind it. Here's the content of server.py: import cherrypy import os import threading class Root(object): ...

What are alternative ways to add an HTML snippet to an existing file without relying on jQuery?

Is it possible to inject the entire content of an HTML file, including all tags, into a specific div using only JavaScript? Alternatively, would it be necessary to append each element individually and create a function for this purpose? ...

Mapping prop passed to client component in NEXT 13: A step-by-step guide

Hello, I'm currently navigating through the Next 13 APP directory and have encountered a scenario where everything functions smoothly when I integrate the server component as shown below: const Tasks = async () => { const { tasks } = await getAll ...

The primary HTML file in Angular is unable to access the styles.scss file located in the src/styles directory

Just starting out with Angular. To incorporate the 7-1 scss pattern into my project, I established a styles folder within the src directory named "src/styles", and connected the components to the src/styles/style.scss file successfully. However, I'm ...

"An excessive number of indices was detected within an array during a loop execution

I'm just starting out with Python and I'm still getting the hang of writing code. Here's what I have so far: N = len(data) i = 0 j = 0 e = 10 while (i<N and j<339) : s[j] = data[i,1] i = i + 14 ...

Determining the position of the selected option in an Angular 2 Select menu

Is there a way to retrieve the position of the selected option in a similar manner to the index of a table? Example for a table: <tr *ngFor="let car of cars; let i = index" (click)="showTabs(i)"> <td>{{i+1}}</td> </tr> I am lo ...

Unable to use .click function to choose image within container

Apologies for the lengthy post, but I believe providing all details is essential to understanding the issue at hand. The following code snippet is intended to display the first image in a pop-up box when a user clicks on any of the images shown: <div ...

Leveraging jQuery's Append functionality

Struggling with using jQuery's .append() method. Check out my code: $('#all ul li').each(function() { if ($(this).children('.material-icons').hasClass('offline-icon') == false) { $('#online ul').append ...

Tips for sending information back to the previous screen in React Native Navigation version 5

Recently, I upgraded to react native navigation version 5 and now I am facing an issue with sending data back to the previous screen when making a goBack() call. To navigate to the next view, I use: const onSelectCountry = item => { console.log(it ...