Using compareWith in Angular Material 2 multiple-select options.
Recently I needed to implement setting some objects as selected per default in the mat-select multiple-choice input options. The user should see the options with pre-filled checkboxes on consequent returns to the form after the data had been saved. Simply binding the ng-model to the options does not do the trick because objects in the options and those in the selected subset from the previously saved data have different identities, or rather changed object references (explained nicely in this story by Netanel Basal). This is where the magic of Angularβs compareWith has come in very handy. In my component, I have an array of User objects people: User[] for the options of mat select (a few hundreds of them in total). The component receives an array of User objects users: User[] as @Input that had been previously persisted in the database. Fair enough (easy to say now that the issue has been solved), User-objects in [people] and User-objects in [users] have different references. And that is why the subset of the options in the multiple select does not initialize with selected checkboxes by default π.
The compareWith just literally compares objects by some given values and the checkboxes get selected, if it returns true.
In my code, I decided to go with the ng-Model binding but it works with formControl as well:
<mat-form-field>
<mat-select multiple[compareWith]="compareFn" name="users
[(ngModel)]="users">
<mat-option *ngFor="let person of people" [value]="person">
{{ person.username }}
</mat-option>
</mat-select>
</mat-form-field>
And in the .ts file I utilize the function from the Angular official documentation to return true if both User objects have the same id:
compareFn(user1: User, user2: User) {
return user1 && user2 ? user1.id === user2.id : user1 === user2;
}
Once done, any User object previously saved in β¦ (wherever you save your data ) gets selected in the options of the mat-select any time the user decides to make changes and gets back to the form, provided both the User model in the data and the User model in the options have got the same id π.
Finally, in the demo-app repository of Angular/Material, they have an example of the compareWith with two implementations: one comparing objects on a given value, and another returning true only if two objects have the same reference. You can find the example here.
Originally published on levelup.gitconnected.com
Related Jobs
Related Articles
Related Issues
- Started
- 0
- 17
- Intermediate
- Submitted
- 1
- 0
- Intermediate
Get hired!
Sign up now and apply for roles at companies that interest you.
Engineers who find a new job through JavaScript Works average a 15% increase in salary.
Start with GitHubStart with TwitterStart with Stack OverflowStart with Email