Use compareWith function from Angular Material mat-select component with linked firebase value
Asked Answered
A

3

14

I'm trying to edit some member's firebase data with a mat-select component composed of different types.

I'm not sure with my structure of nodes but I did this :

member:
    member1:
        name: 
        types:
            typekey1 : Title1
            typekey3 : Title3
            ...

types:
    typekey1:
        key: typekey1
        title: Title1
    typekey2:
        key: typekey2
        title: Title2
    typekey3:
        key: typekey3
        title: Title3   
    ...                 

So I can't make the following function

compareFn(t1: Type, t2: Type): boolean { 
return t1 && t2 ? t1.key === t2.key : t1 === t2;
}

to work with the template

<mat-form-field>
<mat-select [compareWith]="compareFn" [(ngModel)]="member.types" multiple>
<mat-option 
    *ngFor="let type of types | async" 
    [value]="type">
    {{type.title}}
</mat-option>

I can't seem to find the way to connect the two kind of type in the compareFn function and have selected the option when the component is launched

Announce answered 24/11, 2017 at 16:36 Comment(4)
Could you copy paste the actual JSON you are receiving.Refugiorefulgence
Thanks AJT_82 for your reply. I'm not sure I really understand what you mean by "JSON you are receiving". Is it my structure in Firebase? Or some JSON receiving from the compareFn function? And if so how can I copy paste it?Announce
Yes, I mean the result you get from your api. Just click the request in the network tab of dev tools and copy paste the response from the response tab. It's much easier to debug if we have actual data to work with and see how your data is structured :)Refugiorefulgence
{"t":"d","d":{"b":{"p":"prestations/-KztSgj1nuoR8XxvkSrj","d":{"acronyme":"LO","details":"Blabla","price":90,"salon":{"key":"1","title":"DL Paris"},"time":"30","timestamp":1511718837089,"title":"BlablaTitle","types":{"2":"Longs","4":"Man","5":"Woman"}}},"a":"d"}}Announce
C
9

For an object of the following structure:

listOfObjs = [{ name: 'john', id: '1'}, { name: 'jimmy', id: '2'},...]

Define markup like this:

<mat-form-field>
  <mat-select
    [compareWith]="compareObjects"
    [(ngModel)]="obj">
       <mat-option  *ngFor="let obj of listOfObjs" [value]="obj">
          {{ obj.name }}
       </mat-option>
    </mat-select>
</mat-form-field>

And define comparison function like this:

compareObjects(o1: any, o2: any) {
  if(o1.name == o2.name && o1.id == o2.id )
  return true;
  else return false
}
Critter answered 26/4, 2018 at 18:6 Comment(0)
B
5

Here is the example:

<mat-select [compareWith]="compareFn" [(ngModel)]="defaultItem">
    <mat-option *ngFor="let country of countries" [value]="item">
        {{country.name}}
    </mat-option>
</mat-select>

compareFn(c1: Country, c2: Country): boolean {
    return c1 && c2 ? c1.id === c2.id : c1 === c2;
}

Ref: I have answered here, https://mcmap.net/q/830639/-how-to-set-value-in-angular-mat-select-when-component-loading

Buffum answered 22/8, 2020 at 18:33 Comment(1)
Important to note that if your function uses a function, it will break. Instead use a closure: optionCompareFn = (option1: any, option2: any) => this.getOption(option1) === this.getOption(option2); Exterior
R
1
<mat-select [compareWith]="compareFn" [(ngModel)]="defaultItem">
    <mat-option *ngFor="let item of items" [value]="item">
        {{item.title}}
    </mat-option>
</mat-select>

items: Item[];

defaultItem: Item = {
    slug: 'test',
    title: 'Test'
};

compareFn(o1: any, o2: any) {
    return o1.slug === o2.slug;
}
Revisionism answered 23/7, 2019 at 17:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.