可观察:从集合文档中获取唯一的数组值

时间:2019-03-27 19:35:59

标签: angular firebase ionic-framework google-cloud-firestore

从Firestore数组创建唯一值列表的最佳方法是什么?

集合中的每个文档可以具有任意数量的类别,这些类别可以写在文档数组“类别”中。

我试图获取数组值的所有唯一类别以填充过滤选项,因此我需要确保该类别有一家酒店。我不能只使用其他收藏集中的所有类别列表。

Angular 8,Firestore,angularfire 2,Ionic 4

可观察:

# Leave set_fact as it was and then...
- name: kubernetes.yml --> Run the join command on kubernetes nodes
  shell: "{{ hostvars[groups['masters'] | last].join_command }}"
  when: inventory_hostname in groups['nodes']

组件html:

this.hotels = afs.collection('hotels', ref => ref.where('city_id', '==', cityId).orderBy('reviews_number', 'desc')).valueChanges();

结果:

<li *ngFor="let hotel of hotels | async">
{{ hotel.categories }}
</li>

而且我不知道从数组中获取唯一值以便能够使用所有唯一值选项填充下拉列表的最佳实践是什么。

wifi
wifi
wifi,pool,center
pool

2 个答案:

答案 0 :(得分:1)

您可以使用RxJS的 mergeMap()发出单个 hotel 对象, distinct()根据过滤出​​重复项> id ,然后使用
将其压缩回一个数组中 toArray()

this.hotels = afs.collection('hotels', ref => ref.where('city_id', '==', cityId)
  .orderBy('reviews_number', 'desc'))
  .valueChanges()
  .pipe(mergeMap(hotels => hotels), distinct(hotel => hotel.id), toArray());

我还没有使用Firebase,但是如果我不得不猜测, valueChanges()是一个永无止境的流。在这种情况下, toArray()将不起作用,您需要 scan()值并将其压入 array

this.hotels = ...valueChanges().pipe(
  mergeMap(hotels => hotels), 
  distinct(hotel => hotel.id), 
  scan((acc, val) => acc.concat(...val), []));

答案 1 :(得分:1)

为使内容更整洁,我建议使用一个单独的变量来托管您的下拉值,订阅Firestore值,然后获取唯一值

TYPESCRIPT:

class MyComponent {
  dropDownOptions: Array<any> = [];
  someMethod() { // only called once in the component
    this.hotels = afs.collection('hotels', ref => ref.where('city_id', '==', cityId)
      .orderBy('reviews_number', 'desc'))
      .valueChanges();
    this.hotels.subscribe((hotels) => {
      const options: Array<string> = hotels.reduce((prevValue, hotel) => {
        return [...prevValue, ...hotel.categories];
      }, []);

      this.dropDownOptions = options.filter(this.onlyUnique); // get unique values
    })
  }

  onlyUnique(value, index, self) { 
    return self.indexOf(value) === index;
  }

}

HTML:

<select>
  <option *ngFor="let option of dropDownOptions" value="{{option}}">
    {{ option }}
  </option>
</select>

更新:

HTML中有一个错字。即dropdownOptions应该是dropDownOptions。固定它。 另外,我放置了一个Stackblitz example来演示该行为。