How to access the properties of an observable list?


#1

I am loading a list from firebase, this contains 3 attributes, id, date, value. I need to capture all properties (value) to assemble an array and perform a mathematical calculation with them. But when I run a subscribe or try a map, it always returns me undefined in the console.

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams, ToastController, LoadingController } from 'ionic-angular';
import { RecompensaProvider } from '../../providers/recompensa/recompensa';
import { Recompensa } from '../../models/recompensa';
import { Observable } from 'rxjs/Observable';

@IonicPage()
@Component({
  selector: 'page-premios',
  templateUrl: 'premios.html',
})
export class PremiosPage {

  recompensaSaldo : any;
  recompensas : Observable<Recompensa[]>;
  public recompensa = {} as Recompensa;
  public valorTotal : any;

  constructor(public navCtrl: NavController, public navParams: NavParams,
              public toast : ToastController, public recompensaProvider : RecompensaProvider,
              public loading: LoadingController) { 
  }
  

  obterValor() {
      this.recompensas.subscribe(recs => this.valorTotal = recs.map(rec => rec.valor ));
      console.log(this.valorTotal);
  }

  
  ionViewDidLoad() {
    //carregando a minha lista de recompensas
    this.recompensas = this.recompensaProvider.buscarRecompensa(true);
  }  

}

my service :

import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
import { LoginProvider } from '../../providers/login/login';
import { Recompensa } from '../../models/recompensa';

@Injectable()

export class RecompensaProvider {

  recompensaSalva = true;
  
  private caminho: string = '';

  private recompensaColllection: AngularFirestoreCollection<Recompensa>;

  recompensas: Observable<Recompensa[]>;

  constructor(private afs: AngularFirestore, private login: LoginProvider) {

    this.login.usuario.subscribe(auth => {
      if(auth != null)
        {
          this.caminho = '/' + auth.email ;
          this.recompensaColllection = afs.collection<Recompensa>(this.caminho, ref => {
          return ref;
        });
        } else {
          this.caminho = '';
        }
    });
    
  }


  // Método usado para adicionar uma recompensa
  adicionarCliente(recompensa: Recompensa) {
    this.recompensaColllection.add(recompensa);
  }

  
  // Método usado para atualizar os dados de uma recompensa
  atualizarCliente(id: string, recompensa:Recompensa) {
    this.recompensaColllection.doc(id).update(recompensa);
  }


  // Este método será retorna uma lista das recompensas
  buscarRecompensa(recompensaSalva: boolean) {
    return this.afs
      .collection<Recompensa>(this.caminho, ref => {
        return ref.where('recompensaSalva', '==', recompensaSalva);
      })
      .snapshotChanges()
      .map(actions => {
        return actions.map(a => {
          const data = a.payload.doc.data() as Recompensa;
          const id = a.payload.doc.id;
          return { id, ...data };
        })
      });
  }


}

Someone to help? I’m using Firestore


#2

Your console.log is in the wrong place. Only inside the subscribe block is anything you’re expecting to happen going to happen. Angular change detection is generally your friend here: if you put {{valorTotal}} in your template somewhere, it should magically get the right value once the recompensas subscription resolves.


#3

It happens that even if I try to present this variable in my html, it does not appear, it is as if the data had not been retrieved.

Is your analysis, the code right, or is there something you are changing?


#4

No idea, I’ve never touched Firebase.


#5

what would be the right place for my console.log?


#6

Inside the subscription.