We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies.

We use cookies and other tracking technologies to improve your browsing experience on our site, analyze site traffic, and understand where our audience is coming from. To find out more, please read our privacy policy.

By choosing 'I Accept', you consent to our use of cookies and other tracking technologies. Less

We use cookies and other tracking technologies... More

Login or register
to apply for this job!

Login or register
to save this job!

Login or register to start contributing with an article!

Login or register
to see more jobs from this company!

Login or register
to boost this post!

Show some love to the author of this blog by giving their post some rocket fuel 🚀.

Login or register to search for your ideal job!

Login or register to start working on this issue!

Engineers who find a new job through WorksHub average a 15% increase in salary 🚀

Blog hero image

Using compareWith in Angular Material 2 multiple-select options.

Andrey Kolybelnikov 20 October, 2020 | 1 min read

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.1*hk4ks_KR3arTlqGi1_xlXA.png 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

    javascript
    CSS
    HTML
    TypeScript
    Shell
    Python
    golang
    Ruby
    Rust
    vue.js
    Svelte
    AWS
    react
    aws appsync
    GraphQL

Related Issues

viebel / klipse-clj
viebel / klipse-clj
  • Open
  • 0
  • 0
  • Intermediate
  • Clojure
viebel / klipse
  • Open
  • 0
  • 0
  • Intermediate
  • Clojure
viebel / klipse
  • 1
  • 0
  • Intermediate
  • Clojure
viebel / klipse
  • Started
  • 0
  • 1
  • Intermediate
  • Clojure
  • $80
viebel / klipse
  • Open
  • 0
  • 0
  • Advanced
  • Clojure
  • $80
viebel / klipse
  • Started
  • 0
  • 2
  • Advanced
  • Clojure
  • $180
viebel / klipse
  • Started
  • 0
  • 1
  • Intermediate
  • Clojure
viebel / klipse
  • 1
  • 1
  • Advanced
  • Clojure
  • $300
viebel / klipse
  • Open
  • 0
  • 0
  • Intermediate
  • Clojure

Get hired!

Sign up now and apply for roles at companies that interest you.

Engineers who find a new job through WorksHub average a 15% increase in salary.

Start with GitHubStart with Stack OverflowStart with Email