Extract information from checkboxes within a form

Having an issue with retrieving data from a form submission in Angular. The goal is to receive the user-submitted data wrapped in a single object, utilizing formBuilder. However, it seems that formBuilder only works well with <input> tags, as mentioned in a relevant Stack Overflow post.

The constructor defines a form and initializes fields using formBuilder:

component.ts

constructor(private formBuilder: FormBuilder) {
  this.checkoutForm = this.formBuilder.group({
    selectedAccount: '',
    selectedContactInfo: '',
  });
}

In the HTML file, there are options for users to select from a dropdown menu and checkboxes. While the dropdown selection works fine, applying

formControlName="selectedContactInfo"
to the checkboxes' div results in an empty string upon form submission.

component.html

<!-- DROPDOWN - WORKS PERFECT -->
<mat-form-field>
  <mat-label>CHOOSE ACCOUNT</mat-label>
  <mat-select formControlName="selectedAccount">
    <mat-option *ngFor="let account of accounts" [value]="account.name">{{account.name}}</mat-option>
  </mat-select>
</mat-form-field>

<!-- CHECKBOXES - DOESN'T RETRIEVE DATA WHEN FORM IS SUBMITTED -->
<h2 class="mat-h2">CHOOSE TELEPHONE NUMBERS WE CAN CONTACT YOU ON</h2>
     <div formControlName="selectedContactInfo" class="item-container">
         <mat-checkbox>{{contactInfo.privateMobile}}</mat-checkbox>
         <mat-checkbox>{{contactInfo.workMobile}}</mat-checkbox>
     </div>
 

The objective is to capture and store the checkbox data similarly to how the selected account is handled. Whether one or both checkboxes are chosen, the corresponding mobile numbers should be assigned to selectedContactInfo. Array declaration for selectedContactInfo: [] was explored but resulted in null values.

Any insights on resolving this matter would be greatly appreciated.

Edit: To verify the correctness of the submitted form data, the following check is made when submitting the form:

onSubmit(userData) {
  console.log(userData);
}

Answer №1

Could you please review this sample?

@Component({
  template: `
    <form [formGroup]="form">
      <input type="checkbox" formControlName="rememberLogin"> Remember login
    </form>
    <p>Form value: {{ form.value | json }}</p>  
    <!-- {rememberLogin: true } -->
  `,
})
export class App {
  constructor(public fb: FormBuilder) {
    this.form = this.fb.group({
        rememberLogin: [true]
    });
  }  
}

Answer №2

The Challenge

Obtaining an array of numbers based on checkbox selections can be tricky. This solution outlines a method using valueChanges to detect changes in a specific FormControl or FormArray and extract the desired results.

Resolution

To begin, create a FormArray for selectedContactInfo.

contactInfo = {
    privateMobile: 1800124152,
    workMobile: 1800124124
};

this.checkoutForm = this.formBuilder.group({
    selectedAccount: '',
    selectedContactInfo: this.formBuilder.array(Object.keys(this.contactInfo).map(key => false))
});

The FormArray is initialized using keys from the contactInfo object, creating an array with initial values set to false — representing unchecked checkboxes. If defaults need to be checked, mappings to checkboxes should be considered.

Implementing FormArray in the Template

Utilize FormArrayName in the template to access checkbox values (true/false) from selectedContactInfo, utilizing the KeyValuePipe while iterating over contactInfo.

<div class="item-container" formArrayName="selectedContactInfo">
    <ng-container *ngFor="let contactNumber of contactInfo | keyvalue; let i = index">
        <mat-checkbox [formControlName]="i">{{contactNumber.value}}</mat-checkbox>
    </ng-container>
</div>

Mapping the FormArray in valueChanges

Subscribe to valueChanges and map the data to contactInfo into a variable called selectedContactInfo. Differentiate between FormArray and mapped values.

const control = this.checkoutForm.controls.selectedContactInfo;
this.subscription = control.valueChanges.subscribe(value => {
    this.selectedContactInfo = Object.keys(this.contactInfo).map((contactNo, index) => 
        control.value[index] ? this.contactInfo[contactNo] : null
    )
    .filter(contactNo => !!contactNo);
});

This logic extracts numeric values based on checkbox selections, filtering out any unwanted values using null. Remember to unsubscribe from valueChanges after use.

ngOnDestroy() {
    this.subscription.unsubscribe();
}

View StackBlitz Example

Answer №3

The data isn't being returned because formControlName should be added to the checkbox itself, not to divs. Include two contact information fields and utilize those with values, or remove the empty one from the object.

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

Having trouble with the Image Path not connecting from the backend to the frontend of my application

I have been working on getting photos from my backend server and displaying them on my website. The images are stored in the API with a path that looks like localhost:44333/Images/[imagename]. On the frontend, I have tried adding the path dynamically, as ...

Storing the state of DevExtreme DataGrid in Angular

Currently, I have integrated the DevExtreme DataGrid widget into my Angular application. Here is a snippet of how my DataGrid is configured: <dx-data-grid id="gridContainer" [dataSource]="employees" [allowColumnReordering]="true" [allo ...

Unable to transition to a different module by leaping

I recently started using Angular 2 and followed all the instructions, but I'm having trouble loading a component from an external module. Plnkr - Take a look at this code. It's very simple with just 3 links and a few empty components (the app co ...

Can you explain the functionality of templates in the Primeng grid for Angular 6?

In my project, I am incorporating the use of primeng TurboTable which utilizes a pTemplate directive for templates. I am attempting to replicate this approach in order to create a reusable (DUMB) component. Despite my efforts to find a solution, I have not ...

Error Encountered While Submitting Email Form

I'm having trouble with my email submission form on my website. I've checked the code and it seems fine, but for some reason, the submissions are not going through successfully. Even when bypassing the JavaScript and directly using the PHP script ...

Having difficulty in getting the heading to align with the left side

Looking for some guidance on creating a dynamic page similar to this DemoPage. The goal is to have the content editable and pulling data from the backend. However, I am facing challenges in achieving the desired layout as shown in the sample page CreatedPa ...

The React application, when built using `npm run build`, experiences difficulty loading image sources after deployment to App Engine

In my React frontend application, I have the logo.png file being loaded in Header.tsx as an img element like this: <img className={classes.headerLogo} src={'logo.png'} alt={"MY_LOGO"}/> The directory structure looks lik ...

Retrieve the keys of a type by analyzing one of its values

My global type definition consists of an object with keys (referred to as a prop) that must be passed by the user as a parameter to myFunction(), and values that are used solely for type checking within my code. These values can fall into only 3 "possible ...

Thread of Worker, different document from oneself, unable to locate module

Is there a way to separate my worker thread into an external file from the main runtime file? Currently, my folder structure looks like this: src/ > service.ts // my 'main' > thread/ >> test.js In my service.ts file, I have the follo ...

Concealing a component when the page first loads

Seeking help with the functionality discussed in the thread related to toggling table rows in Angular2: Hide/show a table row when clicking on a link in Angular2 Currently, I have a page displaying multiple products, with an option to select a product fro ...

What could be causing the Material AngularJS (CSS) on my website to not function properly, unlike the demo that was

I am completely new to AngularJS and I want to incorporate the material design version of AngularJS for developing a form. I followed the beginner's guide and attempted to create something, but it didn't turn out like the one on the website. So, ...

Discover a magical feature in Angular with the Observable Array and its *ng

I'm encountering an issue that says "ERROR Error: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays." My goal is to establish a Basket store in order ...

Relentless Recursion in Angular's Parent Component

Take a look at the Stackblitz to replicate the issue Hey there! I have an Angular7 application with a parent component named timesheet, and a child component called row. What I'm trying to achieve is having the parent component, timesheet, dynamicall ...

The resource in CosmosDB cannot be found

I have successfully stored documents on Cosmos, but I am encountering an issue when trying to retrieve them using the "read" method. this.cosmos = new CosmosClient({ endpoint: '' key: '' }); this.partitionKey = '/id' thi ...

Showing a solo item from an array in HTML using Angular

How can I display the account name instead of the accountId property value from my list of transaction items? I have a list of transactionitems with an accountId property, and all accounts are loaded in the accounts$ array. However, I am having trouble us ...

The malfunctioning collapse feature in Bootstrap 4 sidebar within an Angular 6 application

I am trying to find a way to collapse and reopen the sidebar when clicking on a button. I have attempted to create a function to achieve this, but unfortunately it did not work as expected. Important: I need to collapse the sidebar without relying on jque ...

Using AJAX and JavaScript to enhance a form before submitting it

As a PHP developer delving deeper into AJAX, I have encountered a perplexing issue that I need help resolving. I am dynamically generating a form like so: function addSearchResult(label, tz) { var html = ''; html += '<div>&ap ...

Achieving the highest ranking for Kendo chart series item labels

Currently, I am working with a Kendo column chart that has multiple series per category. My goal is to position Kendo chart series item labels on top regardless of their value. By default, these labels are placed at the end of each chart item, appearing o ...

Learn how to utilize the "is" status in Postma within your code, even when this particular status is not included in the response

Service.ts Upon invoking this function, I receive a JSON response similar to the following: public signupuser(user: Users): Observable<boolean> { let headers = new Headers(); headers.append('Content-Type', 'application/json&a ...

Encountering 'no overload matches this call' while developing a useReducer using React with Typescript

import { useCallback, useReducer } from "react"; const ARTIST_REDUCER_TYPES = { ADD: "ADD", }; const artistArray = [...Object.values(ARTIST_REDUCER_TYPES)] as const; type ActionReturnedTypes = (typeof artistArray)[number]; type Re ...