LacOniC
LacOniC

Reputation: 934

Angular & Cloud Firestore Observable Does Not Complete

I want to show a message or hide spinner when the observable is complete but Firestore observable is endless i guess. In other words it's "hot" as i understood. Spinner works endless in below code. So;

  1. Isn't there a way to understand if Firestore observable is completed?

  2. If i try to hide spinner in response (data) section, it works as i want in complete. Is this a right way?

  3. I had to unsubscribe observable with ngOnDestroy. Is it because of hot observable also? I've never used unsubscribe before. :/

Here is my service and page:

import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection } from 'angularfire2/firestore';
import { Dining } from '../_models/dining';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class DiningService {
  now = new Date();
  yesterday = new Date(this.now.getTime() - 1000 * 60 * 60 * 24 * 1);

  constructor(public db: AngularFirestore) {}

  getDining() {
    return this.db
      .collection<Dining>('Dining', ref => ref.where('date', '>', this.yesterday))
      .valueChanges();
  }
}

import { Component, OnInit, OnDestroy } from '@angular/core';
import { DiningService } from 'src/app/_services/dining.service';
import { Dining } from '../../_models/dining';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-dining',
  templateUrl: './dining.page.html',
  styleUrls: ['./dining.page.scss']
})
export class DiningPage implements OnInit, OnDestroy {
  list: Dining[] = [];
  msg: string;
  msgColor = '';
  subscription: Subscription;
  showSpinner = true;

  constructor(private diningService: DiningService) {}

  ngOnInit() {
    this.getDining();
  }

  getDining() {
    this.subscription = this.diningService.getDining().subscribe(
      res => {
        this.list = res;
        this.msg = this.list.length === 0 ? 'ERROR_DATA' : '';
        this.msgColor = this.list.length === 0 ? 'danger' : '';
        // this.showSpinner = false;
      },
      err => {
        console.error('Oops:', err.message);
        this.msg = 'ERROR_COM';
        // this.showSpinner = false;
      },
      () => {
        this.showSpinner = false;
      }
    );
  }

  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

Upvotes: 2

Views: 368

Answers (1)

Ashish Ranjan
Ashish Ranjan

Reputation: 12960

All your understanding is correct.

  1. Isn't there a way to understand if Firestore observable is completed?

    The firestore Observable is an event based Observable, it always remains alive to listen if something changed in your db. (You want it to be like this). So, it doesn't complete itself, unless you force it, for example using take(), takeUntil(), etc operators.

  2. If i try to hide spinner in response (data) section, it works as i want in complete. Is this a right way?

    Yes, that is correct, do it in both "success" and "error" callbacks.

  3. I had to unsubscribe observable with ngOnDestroy. Is it because of hot observable also? I've never used unsubscribe before

    Yes, this is the right approach because the Observable doesn't autocomplete, if you don't unsubscribe you will be creating multiple subscriptions everytime you exit and enter the component.

Upvotes: 3

Related Questions