Hone logo
Hone
Problems

Dynamic Form Field Generation with Angular FormArray

This challenge focuses on building a dynamic form in Angular where the number of form fields can be controlled by the user. You'll learn how to leverage Angular's FormArray to manage a collection of form controls, enabling flexible and interactive user input.

Problem Description

You are tasked with creating an Angular component that allows users to dynamically add and remove "item" entries. Each "item" should have at least two input fields: a "name" and a "quantity". The component should allow the user to add as many items as they wish and remove any existing item. The data from these dynamically generated fields needs to be accessible as a structured array.

Key Requirements:

  • Dynamic Addition: Users must be able to click a button to add a new "item" entry.
  • Dynamic Removal: Users must be able to click a button next to each "item" to remove it.
  • Item Structure: Each "item" should consist of at least two input fields: "name" (string) and "quantity" (number).
  • FormArray Implementation: Use Angular's FormArray to manage the collection of "item" form groups.
  • Data Retrieval: Provide a way to access the collected data from the FormArray as a plain JavaScript array of objects (e.g., [{ name: 'Apple', quantity: 5 }, { name: 'Banana', quantity: 3 }]).

Expected Behavior:

  • When the component loads, it should display at least one initial "item" entry.
  • Clicking "Add Item" should append a new set of "name" and "quantity" input fields to the form.
  • Clicking the "Remove" button next to an "item" should delete that specific "item" entry from the form.
  • The "name" input should accept string values.
  • The "quantity" input should accept numeric values.
  • A button or mechanism should be available to display or submit the collected form data.

Edge Cases to Consider:

  • Removing the last item from the form.
  • Handling empty input fields.
  • Ensuring the "quantity" field only accepts valid numbers.

Examples

Example 1:

Initial State (Component Loaded):

  • UI: Displays one "Item 1" with empty "Name" and "Quantity" fields, and an "Add Item" button.
  • Form Structure (Conceptual):
    {
      items: [
        { name: '', quantity: '' }
      ]
    }
    

After Adding One Item:

  • UI: Displays "Item 1" and "Item 2", each with empty input fields, and an "Add Item" button. Each item also has a "Remove" button.
  • Form Structure (Conceptual):
    {
      items: [
        { name: '', quantity: '' },
        { name: '', quantity: '' }
      ]
    }
    

After Filling and Removing an Item:

  • UI: User fills "Item 1" with Name: 'Apple', Quantity: 5. User clicks "Add Item". User fills "Item 2" with Name: 'Banana', Quantity: 3. User clicks the "Remove" button next to "Item 1". The UI now shows only "Item 2" (labeled as "Item 1" after removal).
  • Form Structure (Conceptual):
    {
      items: [
        { name: 'Banana', quantity: 3 }
      ]
    }
    
  • Retrieved Data:
    [
      { "name": "Banana", "quantity": 3 }
    ]
    

Example 2:

Scenario: Removing the Last Item

  • UI: User has two items. User clicks "Remove" on the second item, leaving only one. User then clicks "Remove" on the now-only item.
  • Expected Behavior: The form should not be entirely emptied. It should ideally reset to a single empty item or prevent removal of the last item (depending on desired UX). For this challenge, allow removal, but consider the reset state. If all items are removed, a single new item should ideally be added automatically or the UI should clearly indicate no items are present.

Constraints

  • Angular version: 14+
  • TypeScript version: 4.0+
  • Use @angular/forms module for form handling.
  • The component should be a standalone component or part of a module.
  • The solution should be implemented within a single Angular component (.ts, .html, .css if necessary).

Notes

  • Consider using FormBuilder to simplify the creation of your form controls and groups.
  • Think about how you will associate a "Remove" button with each individual item in the FormArray.
  • When retrieving the data, ensure that the quantity is a number, not a string, if it was entered as such. You might need to do some type casting or validation.
  • The "name" of the item in the UI (e.g., "Item 1", "Item 2") can be generated programmatically based on its index in the FormArray.
Loading editor...
typescript