-2
this._userService.getUsers().subscribe((userData) =>
            this.users = userData.filter((x, i, a) => x && a.indexOf(x) === i));

I tried using this with the algorithm that it returns the unique values when the index of the object is the same as the first index of the object in the array. But it doesnt seem to work? I know how to filter based on certain condition i.e. user.age > 20. But how do I filter unique values in Angular for a drop down list, i.e. Male and Female?

pepega
  • 25
  • 8
  • What is the type of response you are getting? – Navitas28 Aug 13 '20 at 05:08
  • Do you want to get `unique` value of `gender` (I guess) `property` from your list of `userData` `object`? – Karan Aug 13 '20 at 05:15
  • If you only need a list of unique values for a certain property, have a look at the second answer here (the one using `...new Set`): https://stackoverflow.com/questions/15125920/how-to-get-distinct-values-from-an-array-of-objects-in-javascript – Gunnar B. Aug 13 '20 at 05:29
  • I want to return a list of user objects which have been filtered according to a unique property, i.e. gender. So I can display the unique property to the html view using interpolation in Angular. – pepega Aug 13 '20 at 05:55
  • You just need the distinct list to populate a drop down? At least thats what I understand from your comments. In that case I don't see why you would need a whole user object (which for gender would be the first male and the first female person if thats the only two distinct genders you have). The rest of those object properties would not have any logical connection to the drop down. – Gunnar B. Aug 13 '20 at 07:15

2 Answers2

2

After getting your userData lets say you want to display unique values of attribute team so what you can do is first filter all the team values from each user object and make a array of teams and then you can filter that array to get unique values for your dropdown.

let userData = [{
      id: 1,
      name: "Buddy Sample",
      team: "SDR",
    },
    {
      id: 2,
      name: "Claudianus Stachini",
      team: "BDR",
    },
    {
      id: 3,
      team: "SDR",
      name: "John Doe"
    },
    {
      id: 4,
      team: "SDR",
      name: "John Doe"
    },
    {
      id: 5,
      team: "JKL",
      name: "John Doe"
    }];
    
    console.log("The user Teams data : ", userData);

let uniqueTeams = userData
    .map((el, key) => el.team)
    .filter((item, i, ar) => ar.indexOf(item) === i);
    
console.log("The unique set of teams :" , uniqueTeams);

Happy Coding!

Milan Lakhani
  • 528
  • 3
  • 13
  • Thanks, but I want to return a list of user objects, not a list of strings, how can I do that? – pepega Aug 13 '20 at 05:46
  • Do you simply want to separate males from females in your array. i.e you want and array of objects that is males and other array object who are females? Am I getting you right? – Milan Lakhani Aug 13 '20 at 06:05
  • Alright so basically I am subscribing to an observable from an Angular service, obtaining a list of user objects in a component. And I want to display a drop down list for a form in a view, which shows the gender property of the user objects. But since there are multiple users in the database, there will be multiple entries of i.e. Male, Female, Female, Male, Male etc. Thus, I want to filter the subscribed user objects in such a way that I can remove the duplicates and only display Male and Female in the drop down list. – pepega Aug 13 '20 at 06:11
  • Sorry I was a pepeg, I managed to filter it based on unique gender. Problem was that model property name was not the same as the database property name.. – pepega Aug 13 '20 at 07:54
1

From what could gather of your comments you only really need the distinct values among a certain property (e.g. gender) of your User-List to populate a drop-down.

In that case I would do something like this:

users: User[];
genders: string[] = [];  // bind drop down to this, initialization as [] to prevent undefined error

constructor(...){...}

ngOnInit() {
  this._userService.getUsers().subscribe((userData) => {
    this.users = userDate;
    this.genders = [...new Set(userData.map(x => x.gender))];
  });
}

Of course this is missing unsubcription from _userService.

Gunnar B.
  • 2,879
  • 2
  • 11
  • 17
  • Wow. It didn't work at first and I was wondering why. Turns out it was because the property names in the model User is different from the property names in the database... After I made it uniform, it worked. Thanks – pepega Aug 13 '20 at 07:45
  • Do you know how to filter another property in a drop down list based on the gender property? i.e. There are only S and M for females, while there are only L and XL for males? – pepega Aug 13 '20 at 09:05
  • I have already selected the conditions by retrieving the values of the dropdown list using [(ngModel)], but I am not sure how to proceed – pepega Aug 13 '20 at 09:11
  • If those are fixed I would probably just add a const object somewhere like `export const sizes = { male: ['L', 'XL'], female: ['S', 'M'] } as const`, bind the value of `gender select` to a `*ngIf='male male-select-template else female-select-template'` and then have two templates `#male-select-template` and `#female-select-template`, one with `*ngFor='let s of sizes.male'` and the other with `sizes.female`. – Gunnar B. Aug 13 '20 at 09:14
  • Actually, if the genders are fixed, I'd probably be easier to have them as a list somewhere as well instead of extracting them from the users. – Gunnar B. Aug 13 '20 at 09:17