Search code examples
angularobservableangular-services

Angular 5 - Observables: Can't access the value of a document using Firestore


I can't get the value of a document when I trie to get it using its id, when I displays the variable in the console it display

Observable {_isScalar: false, source: Observable, operator: MapOperator}

this the definition of my function in my service

getDataDetails(id: any) {
    this.dataDocumment = this.afs.doc('economie/' + id);
    return this.dataDocumment.valueChanges();;
  }

this is my template

<div class="main-content">
  <div class="container-fluid">
      <div class="header text-center">
          <h3 class="title">{{dataD.adresse | async | json}}</h3>
          <p class="category">Ensemble d'informations sur les communes prioritaires ou intervient CPDEP</p>
      </div>
      <div class="places-sweet-alerts">
          <div class="row">
              <div class="col-md-12">

                  <div class="card">
                      <div class="card-header card-header-icon" data-background-color="red">
                          <i class="material-icons">assignment</i>
                      </div>
                      <div class="card-content">
                          <h4 class="card-title">Présentations des communes</h4>
                          <div class="toolbar">



                                  <div class="col-lg-2"></div>
                                  <div class="col-lg-8">
                                      <div class="card">
                                          <div class="card-header card-header-danger" data-background-color="red">
                                              <h4 class="card-title">Circonscription de </h4>
                                              <p class="category">Département du </p>
                                          </div>
                                          <div class="card-content">
                                              <ul class="list-group list-group-flush">
                                                  <li class="list-group-item">Arrondissement : </li>
                                                  <li class="list-group-item">Nombre de sections communales : </li>
                                                  <li class="list-group-item">Organisation : </li>
                                                  <li class="list-group-item">Superficie : </li>
                                                  <li class="list-group-item">Population : </li>
                                                  <li class="list-group-item">Economie : </li>
                                                  <li class="list-group-item">Nombre de centres de vote : </li>
                                                  <li class="list-group-item">Nombre de bureaux de vote : </li>
                                                  <li class="list-group-item">Nombre d'électeur : </li>

                                              </ul>
                                          </div>
                                      </div>

                                  </div>
                                  <div class="col-lg-2"></div>
                              

                          </div>

                      </div>
                      <!-- end content-->
                  </div>
                  <!--  end card  -->
              </div>
              <!-- end col-md-12 -->
          </div>
      </div>
  </div>
</div>

and this my my component code

import { Component, OnInit } from '@angular/core';
import { EconomieService } from '../../services/economie.service';
import { Router, Params, ActivatedRoute} from '@angular/router';
@Component({
  selector: 'app-economie-detail',
  templateUrl: './economie-detail.component.html',
  styleUrls: ['./economie-detail.component.scss']
})
export class EconomieDetailComponent implements OnInit {
  id : string ;
  dataD : any;
  constructor(private eco: EconomieService,private route: ActivatedRoute) { }

  ngOnInit() {
    this.id = this.route.snapshot.params['id'];
    this.dataD = this.eco.getDataDetails(this.id);
  }
}

Any idea of what is going wrong?


Solution

  • According to the AngularFire2 documentation, Stream Document Data using valueChanges() returns an Observable which needs to be unwrapped to get the actual data.

    You'll have to subscribe to it to get the value.

    You might also want to consider simply using an async pipe so as to not unsubscribe from the subscription to avoid any memory leaks.

    So, considering this function is exposed from a service named DataService, wherever you're using this function, just do this:

    import { Component, Input } from '@angular/core';
    
    @Component({
      ...
    })
    export class HelloComponent  {
    
      data;
      data$;
    
      constructor(private dataService: DataService) {}
    
      ngOnInit() {
        this.dataService.getDataDetails('someId').subscribe(data => console.log(data));
    
        // OR
        this.data$ = this.dataService.getDataDetails('someId');
    
      }
    
    }
    

    And then, in your template:

    {{ data$ | async | json }}
    

    This will unwrap the Observable when being passed through the async pipe. Whatever is the output of the async pipe will be passed through the json pipe which will stringify the JSON Object into string. And that's what will get printed on to the string. Hope it makes sense now.

    For your Specific Use Case

    Use this:

    {{ (dataD | async)?.adresse }}
    

    Here's a StackBlitz if that helps. I'm pretty sure that should make it work. Here's the sort of data that I have in the Cloud Firestore.

    enter image description here