Using Angular, create mat-checkbox components that are dynamically generated and bound using

In my Offer class, I have a property called "units" which is an array of objects.

export class Offer {
   public propertyA: string;
   public propertyB: string;
   public units: Unit[];
}

export class Unit {    
    public code: string,
    public name: string,
    public checked: boolean
}

I am developing with Angular 2 and want to display these units as selectable checkboxes for the user. I am also utilizing angular material components.

The HTML implementation looks like this:

<div *ngFor="let unit of model.units; let i=index">
  <mat-checkbox [(ngModel)]="model.units[i].checked"
    id="units[{{i}}]" name="units[{{i}}]">
       {{ unit.name }}
  </mat-checkbox>                        
</div>    

To load the units property, I use the following:

this.model.units.push(new Unit("code1","name1", false));
this.model.units.push(new Unit("code2","name2", false));
this.model.units.push(new Unit("code3","name3", false));

However, when I submit the form, the checked property does not retain the selected values. What could be causing this issue?

Answer №1

To implement one-way binding, add [checked]="unit.checked" and remove ngModel, id and name attributes from your mat-checkbox.

If you want to achieve two-way binding, you can follow a similar approach used in this example:

In your HTML file:

<div *ngFor="let unit of model.units">
  <mat-checkbox [checked]="unit.checked" 
  (change)="valueChange(model.units, unit, $event)">
       {{ unit.name }}
  </mat-checkbox>                        
</div>

Add the following method to your component file:

valueChange(model.units, unit, $event) {
        // set the two-way binding for the specific unit with the event
        model.units[unit].checked = $event.checked;
    }

UPDATE: To enable two-way binding without explicit handling, ensure that each item in model.units has a checked property.

In your component file:

this.model.units.forEach(item => {
                       item.checked = false; // adjust as needed
                    });

In your HTML file:

 <div *ngFor="let unit of model.units; let i=index">
    <mat-checkbox [(ngModel)]="unit.checked" [checked]="unit.checked"                                                                                    
    name="{{i}}-name">                             
    </mat-checkbox>
</div>

If you also want to control the enable/disable options, you can add the following:

In your component file:

this.model.units.forEach(item => {
                       item.checked = false; // adjust as needed
                       item.disabled = true; // adjust as needed
                    });

In your HTML file:

<div *ngFor="let unit of model.units; let i=index">
        <mat-checkbox [(ngModel)]="unit.checked" [checked]="unit.checked"
         [disabled]="unit.disabled"                                                                                    
       name="{{i}}-name">
        </mat-checkbox>
    </div>

Answer №2

I have successfully tested this code in Angular 7.

It is important to ensure that each checkbox has a unique name.

<mat-grid-list cols="4" rowHeight="100px">
                    <mat-grid-tile *ngFor="let item of aspNetRolesClaims" [colspan]="1" [rowspan]="1">
                        <span>{{item.claimValue}}</span>
                        <mat-checkbox [(ngModel)]="item.claimValue" name="{{item.claimType}}">{{item.claimType}}</mat-checkbox>
                    </mat-grid-tile>
                </mat-grid-list>

Answer №3

After testing in Angular 7, I did not encounter any errors related to your question. Feel free to check out a live demo on this StackBlitz example. Here is my response:

To ensure functionality, be sure to assign a unique name to the ngModel bound input.

Here's an example using your code snippet:

<div *ngFor="let unit of model.units; let i=index">
  <mat-checkbox 
    [(ngModel)]="model.units[i].checked"
    id="units-{{i}}" 
    name="units-{{i}}" // instead of array notation
  >
      {{ unit.name }}
  </mat-checkbox>                        
</div> 

In personal practice, I avoid using array notation like units[{{i}}] as it can merge all fields together, although it doesn't seem to be causing issues in your current implementation.

Answer №4

If you find yourself unable to utilize [(ngModel)] in situations where a FormGroup is employed, here's an alternative approach. In this scenario, it is assumed that 'obj' represents a custom object with an 'IsSelected' property.

<mat-checkbox [checked]="obj.IsSelected"                                      
 (change)="onSelectionChanged($event, obj)">{{obj.Name}}
</mat-checkbox>

To manually update the 'obj.IsSelected' property within the 'onSelectionChanged' method.

public onSelectionChanged(arg: MatCheckboxChange, obj:any) {
 obj.IsSelected = arg.checked;
}

Answer №5

Here is an alternative approach that may offer a simplified solution. This method has been proven effective when used within a form group.

<form [formGroup]='formGroup'>
    <mat-checkbox [(ngModel)]="obj.IsSelected" [ngModelOptions]="{standalone:> true}">
        {{obj.Name}}
    </mat-checkbox>
</form>

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

Angular 10 Reactive Form - Controlling character limit in user input field

I'm currently developing an Angular 10 reactive form and I am looking for a way to restrict the maximum number of characters that a user can input into a specific field. Using the maxLength Validator doesn't prevent users from entering more chara ...

The angular-oauth2-oidc library is having issues loading the jsrsasign module

I'm currently working on upgrading a dependency in Angular for a project that was forked from: https://github.com/mgechev/angular-seed The dependency in question is located at: https://github.com/manfredsteyer/angular-oauth2-oidc. However, I'm f ...

Tips for achieving server-side pagination with client-side sorting

Currently utilizing Angular Material's data grid, successfully loading data from the server side with sorting and pagination functionality. However, I am attempting to sort only the items visible on the table instead of sorting from the server side. ...

Ensuring consistency between TypeScript .d.ts and .js files

When working with these definitions: https://github.com/borisyankov/DefinitelyTyped If I am using angularJS 1.3.14, how can I be certain that there is a correct definition for that specific version of Angular? How can I ensure that the DefinitelyTyped *. ...

Stop automatic variable updates in Angular

In Angular, variable x is assigned to variable y. Whenever variable x changes, y also gets changed. How can this behavior be prevented? ngOnInit() { this.editFunction() } editFunction(){ for (let i = 0; i < this.editingData["tags"].length; i ...

Exploring Angular 5: Injecting a Service in Unconventional Places

I am attempting to utilize a service outside of a component. My main objective is to use my service within a function wrapped in a data object that I would then pass to my router for use by my Breadcrumb later on. Here is an example of what I envision: ...

Exploring the Contrasts: ng add <package name> versus npm install <package name> in Angular 6

With the recent release of Angular6, a new command called ng add has been introduced. I am curious to know what sets this apart from the traditional npm install <package> and ng add <package>. ...

What is the best way to pass a value to a modal and access it within the modal's component in Angular 8?

How can I trigger the quickViewModal to open and send an ID to be read in the modal component? Seeking assistance from anyone who can help. Below is the HTML code where the modal is being called: <div class="icon swipe-to-top" data-toggle="modal" da ...

Clicking on the sub kendo panelbar item activates the parent kendo panelbar item

Utilizing a Kendo Angular UI panelbar within the sidepanel as a treemenu with submenu's, each item is linked to the Angular router routes array via routerLink. An issue arises when opening the submenu, where the parent menuitem's path is followe ...

I seem to be failing at properly executing Promises... What crucial element am I overlooking in this process?

Within my project, there exists a file named token.ts which contains a function that exports functionality: import * as jwt from 'jsonwebtoken'; import { db, dbUserLevel } from '../util/db'; export function genToken(username, passwor ...

Angular 4 Filtering Pipe: Simplify Data Filtering in Angular

Attempting to replicate AngularJS's OrderBy feature. Working with an array like this, I am aiming to filter the cars by their car category. [ { "car_category": 3, "name": "Fusion", "year": "2010" }, { "car_category": 2, "na ...

Tips for incorporating user access control logic into a lazy-loaded Angular Monorepo application without embedding the logic in the main application

In our current project, we are developing an Angular application utilizing the Angular monorepo structure. This setup includes a parent application and several children applications, with the parent application located in the `app` folder and the children ...

What is the process for displaying the attributes of a custom object in Typescript?

I need help returning an array of prop: value pairs for a custom object using the myObject[stringProp] syntax. However, I keep encountering this error message: TS7053: Element implicitly has an 'any' type because expression of type 'str ...

Tips for switching between two icons within the same div by clicking on the icon

I am looking to implement a feature in angular2 that is similar to marking an email as Starred. For example, when I click on the empty star icon, it will make some service calls to check if the item should be starred. If the result is true, then a new icon ...

Is it necessary to verify the apiKey or does the authentication of the user suffice for an HTTPS callable function?

I'm interested in creating a cloud function that can be executed from both the client and the backend. After exploring the documentation, I learned that an HTTPS callable function will automatically include user authentication data, accessible through ...

Placeholder variable not specified in radio buttons

I am currently facing challenges applying validations to radio buttons in Angular. Normally, I create a #templateRefVariable on the input for other input types, which allows me to access the NgControl and use properties like touched. My goal is to set the ...

Examining Axios HttpService piping through a NestJS middleware in a unit test

A middleware function retrieves a JSON document from a microservice endpoint and appends it to the request. The good path test is successful, but I'm struggling to make the bad path test throw a ForbiddenException and stop it from invoking next(). W ...

Issue with logging messages using console.log in Knex migration script

My concern: I am facing an issue where the console.log('tableNobject: ', tableNobject) does not get logged in my knex migration script. I have attempted the following code snippets: //solution A export async function up(knex: Knex) { const ta ...

Determining the best method for change detection in Angular 2: Choosing between Observable, EventEmitter, and Dot Rule

Managing change detection in Angular2 can be approached in three different methods that I have observed. Utilizing Observables @Injectable() export class TodosService { todos$: Observable<Array<Todo>>; private _todosObserver: any; ...

conditional operator that compares values in router events

As I examine an object, links = { link1: 'page1', link2: 'page2', link3: 'page3', link4: 'page4', link5: 'page5', link6: 'page6' } I possess a function for retrieving t ...