Khaled Ramadan
Khaled Ramadan

Reputation: 832

Why subscribe method is working twice?

I'm subscribe firebase list in ionic2 project.

This is my function inside the service:

  getLastOrderBeta() {
    return this.db.list(`Ring/${localStorage.getItem('localstorage')}`, {
        query: {
          equalTo: false,
          orderByChild: 'status',
          limitToLast: 2,
        }
      })
      .map((orders: any) => {
        return orders.map((order: any) => {
          order.userInfo = this.getProfile(order.userid);
          return order;
        });
      });
  }

This is my subscribe:

  subscribeOrder(){
    this.orderList = this.orderProvider.getLastOrderBeta();
    this.orderList.subscribe((s: any) => {
      this.selectedOrder = "";
      console.log(this.playSound,"outside the if");
      if (this.platform.is('cordova') && this.playSound && s.length) {
          console.log(this.playSound,"inside the if");
          this.audioProvider.playRingTone();
      }
      this.playSound = true;
    });
  }

The subscribeOrder() logs showed twice.

this is my html code:

 <ng-container *ngIf="orderList | async as orders">
    <span *ngFor="let order of orders?.slice().reverse(); let first = first; let last = last">
      <ng-container *ngIf="first && !selectedOrder" [ngTemplateOutlet]="orderView" [ngTemplateOutletContext]="{order:order,selected:false}"></ng-container>
      <ng-container [ngTemplateOutlet]="last && (last !== first) ? beforeLastOrder : waiting" [ngTemplateOutletContext]="{order:order}"></ng-container>
    </span>
    <ng-container *ngIf="!orders.length">
      <ion-fab bottom left>
        <button (click)="logOut()" ion-fab mini>
          <ion-icon name="power"></ion-icon>
        </button>
        <button (click)="openSettings()" ion-fab mini>
          <ion-icon name="wifi"></ion-icon>
        </button>
      </ion-fab>
      <span *ngIf="batterPercentage" class="battery">{{batterPercentage}}%</span>
      <img *ngIf="!selectedOrder" class="rnb-img-waiting" src="assets/logo.png">
      <ion-item (click)="showModal()" class="ion-footer">
        <span class="no-orders">Previous Orders</span>
      </ion-item>
    </ng-container>
  </ng-container>

Any explanation for this duplication an how can i solved.

Thanks.

Upvotes: 0

Views: 66

Answers (2)

Khaled Ramadan
Khaled Ramadan

Reputation: 832

I found the solution,

After debugging I found the problem was from the Angularfire2 query and exactly from the limitToLast.

So I disabled the limitToLast. And I created a code have the same role.

To became:

return this.db.list(`Ring/${localStorage.getItem('localstorage')}`, {
    query: {
      equalTo: false,
      orderByChild: 'status'
    }
  })
  .map((orders:any)=>{return orders.slice(-2)})
  .map((orders: any) => {
    return orders.map((order: any) => {
      order.userInfo = this.getProfile(order.userid);
      return order;
    });
  })  as FirebaseListObservable<any[]>;

and that is work properly.

Thanks.

Upvotes: 0

Boris Lobanov
Boris Lobanov

Reputation: 2454

For your case, I'm guessing there are two solutions:

  1. Don't use async pipe at all, just save the data from firebase in subscribe and feed it to the template:

     subscribeOrder(){
        this.orderList = this.orderProvider.getLastOrderBeta();
        this.orderList.subscribe((s: any) => {
          this.selectedOrder = "";
          console.log(this.playSound,"outside the if");
          if (this.platform.is('cordova') && this.playSound && s.length) {
              console.log(this.playSound,"inside the if");
              this.audioProvider.playRingTone();
          }
          this.playSound = true;
          this.orders = s;
        });
      }
    

Then in your template:

  1. Use async pipe but replace the subscribe in your component with a do operator if you need a side effect:

    subscribeOrder(){
        this.orderList = this.orderProvider.getLastOrderBeta()
            .do((s: any) => {
              this.selectedOrder = "";
              console.log(this.playSound,"outside the if");
              if (this.platform.is('cordova') && this.playSound && s.length) {
                  console.log(this.playSound,"inside the if");
                  this.audioProvider.playRingTone();
              }
              this.playSound = true;
              this.orders = s;
            });
          }
    

Upvotes: 2

Related Questions