Search code examples
javascriptarraysfirebaseionic3angularfire2

Ionic 3 - Filter a List from an User-sorted Array


I am developing an app with Ionic and Firebase which needs to compare the Array produced by the user with the Array in Firebase to filter a list of products.

There is a list containing 3 items (A, B and C) that can be reordered by the user. This order should be used to filter products from another list, which have the characteristics A, B and C, with a score and sorted in descending order.

So I need to compare the sorting made by the user and only result in products with the same sorting. For example, if the user sorts B, A, C, only products with that same sort order will be displayed in the result. That means a product that has A = 50, B = 100, C = 30, will have the Array desOrder = [B, A, C].

The Firebase is something like this:

- XMnL8KVlJXXXXXXXXXX
    name: "Product 1"
    - desOrder
        0: "B"
        1: "A"
        2: "C"
- XMnX2KVlJXXXXXXXXXX
    name: "Product 2"
    - desOrder
        0: "C"
        1: "B"
        2: "A"
- XnP33RRmNXXXXXXXXXX
    name: "Product 3"
    - desOrder
        0: "A"
        1: "C"
        2: "B"

search.html

<ion-list no-lines>
  <ion-item-group class="reordenar" reorder="true" (ionItemReorder)="reorderItem($event)">
    <ion-item *ngFor="let item of orderItems">
      {{ item }}
    </ion-item>
  </ion-item-group> 
</ion-list>

search.ts

orderItems: any;

constructor(public navCtrl: NavController, public navParams: NavParams) {
   this.orderItems = ["A", "B", "C"];
}

reorderItem(indexes){
   this.orderItems = reorderArray(this.orderItems, indexes);
   console.log(this.orderItems); // can be, e.g., ["B", "C", "A"]
}

searchTo(){
   this.navCtrl.push(ListPage, {this.orderItems}); 
}

For now, I am returning all products, without any filter:

list.ts

products: any;

constructor(public navCtrl: NavController, public navParams: NavParams, public listservice: ListService) {
this.getaData();
}

getaData(){
  this.products = this.listservice.getAll();
}

list-service.ts

getAll(){
  return this.db.list('product/').snapshotChanges()
  .map(changes =>{
    return changes.map(c=> {
      const data = c.payload.val();
      const id = c.payload.key;
      return { id, ...data };;
    });
  })
}

The important thing is the ordering, since all products have the 3 characteristics and their scores (it's not the same on this question)


Solution

  • If you're trying to filter to only display items with the same order, add a single property to each item with the order. So in your example: ["B", "C", "A"], this would become a property "itemOrder": "BCA".

    With this you can now filter on this property: ref.orderByChild("itemOrder").equalTo("BCA").

    Since I think this may already be the purpose of your desOrder property, you may also consider changing that from an array to a string.