title: Angular / Firestore - snapshotChanges() Map printing a document to the console 5 times
body: <p><strong>What I'm using</strong></p>
  
  <ul>
  <li>Angular</li>
  <li>Firebase</li>
  </ul>
  
  <p><strong>What I'm doing</strong></p>
  
  <ul>
  <li><p>I click on an item from a collection list</p></li>
  <li><p>This item links to a document view</p></li>
  <li><p>I display the document</p></li>
  <li><p>Instead of using <strong>valueChanges()</strong>, I need to update the returned date.</p></li>
  <li><p>I update the returned date by using <strong>snapshotChanges()</strong></p></li>
  </ul>
  
  <p><strong>The Issue</strong></p>
  
  <ul>
  <li><p>This mostly works fine and returns the data and I have correctly formatted the returned date</p></li>
  <li><p>However, the consoles prints the document 5 times</p></li>
  </ul>
  
  <p><strong>Question</strong></p>
  
  <ol>
  <li>Have I approached this correctly? As this is the approach I'll probably aim to use to fetch the <strong>downloadURL</strong> from storage too</li>
  <li>Why is the document appearing 5 times in the console? (Screenshot attached)</li>
  </ol>
  
  <p>Any assistance would be greatly appreciated! :)</p>
  
  <p><strong>Component TS</strong></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>import { Component, OnInit } from '@angular/core';
  
  // Firestore
  import { Observable } from 'rxjs/Observable';
  import { AngularFirestore, AngularFirestoreDocument } from 'angularfire2/firestore';
  
  // Routes
  import { Router, ActivatedRoute } from '@angular/router';
  
  // Moment JS
  declare var moment: any;
  
  @Component({
    selector: 'app-albums-detail',
    templateUrl: './albums-detail.component.html',
    styleUrls: ['./albums-detail.component.css']
  })
  
  export class albumsDetailComponent implements OnInit {
  
    folderId: string;
    albumId: string;
  
    private albumDoc: AngularFirestoreDocument&lt;any&gt;;
    album: Observable&lt;any&gt;;
  
    constructor(
      private readonly afs: AngularFirestore,
      private activatedRoute: ActivatedRoute,
      private router: Router) { }
  
  
    ngOnInit() {
  
      // Look at the url for the Folder and album ID and set the local variable
      this.activatedRoute.params.forEach((urlParameters) =&gt; {
        this.folderId = urlParameters['folderId'];
        this.albumId = urlParameters['albumId'];
      });
  
      // Return the albums list
      this.getalbumData();
  
    }
  
   
    getalbumData() {
      this.albumDoc = this.afs.doc(`folders/${this.folderId}/albums/${this.albumId}`);
      //this.album = this.albumDoc.valueChanges();
  
      this.album = this.albumDoc.snapshotChanges().map(action =&gt; {
  
        const id = action.payload.id;
        const data = action.payload.data();
  
        // Get the date from each album
        var albumDateTimestamp = data.album_date;
  
        // Convert the unix value and format it based on the users locale setting
        var albumDateISO = moment(albumDateTimestamp).format("DD/MM/YYYY");
  
        // Create a new 'name' to use in the HTML binding
        data.formattedDate = albumDateISO;
  
        console.log(data);
  
        return { id, ...data };
  
      });
  
    }
  }</code></pre>
  </div>
  </div>
  </p>
  
  <p><strong>Component HTML</strong></p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;h1&gt; {{ (album | async)?.album_title }} &lt;/h1&gt;
  &lt;div&gt;
    {{ (album | async)?.album_title }}
    {{ (album | async)?.formattedDate }} 
    {{ (album | async)?.album_client }}
    {{ (album | async)?.album_reference }}
  &lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p><strong>UPDATE</strong></p>
  
  <p>I've asked this question in a couple of places and tweeted a few people without much luck, so i've tried a new way. I'm not entirely sure it's clean, but it works. It's not using AngularFire anymore as I can't for the life of me figure out why it prints to the console so many times. I took an example straight from the firestore docs. I have a bunch of global variables which i update after grabbing the data and use that for my data binding. It feels like it's fetching / reading the data each time I load the page. Is there a way of checking?</p>
  
  <p>If anyone can let me know if this is a legitimate way of performing this action, that would be awesome :D</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code> getProjectData() {
  
  
      var db = firebase.firestore();
  
      var docRef = db.collection(`folders/${this.folderId}/albums`).doc(`${this.albumId}`);
  
      docRef.get().then((doc) =&gt; {
        if (doc.exists) {
          console.log("Document data:", doc.data());
          var data = doc.data();
          var id = doc.id;
          this.shazam(data, id);
        } else {
          console.log("No Such Document");
        }
      });
  
    }
  
  
  
  shazam(data, id) {
  
  
      var albumTimeStamp = data.album_date;
  
      // Convert the unix value and format it based on the users locale setting
      var albumDateIso = moment(albumTimeStamp).format("DD/MM/YYYY");
  
      // Create a new 'name' to use in the HTML binding
      data.formattedDate = albumDateIso;
  
      this.albumTitle = data.project_title;
      this.albumDate = data.formattedDate;
  
    }</code></pre>
  </div>
  </div>
  </p>
  
  <p><a href="https://i.stack.imgur.com/ocCS5.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ocCS5.png" alt="enter image description here"></a></p>