What I'm using
- Angular
- Firebase
What I'm doing
I click on an item from a collection list
This item links to a document view
I display the document
Instead of using valueChanges(), I need to update the returned date.
I update the returned date by using snapshotChanges()
The Issue
This mostly works fine and returns the data and I have correctly formatted the returned date
However, the consoles prints the document 5 times
Question
- Have I approached this correctly? As this is the approach I'll probably aim to use to fetch the downloadURL from storage too
- Why is the document appearing 5 times in the console? (Screenshot attached)
Any assistance would be greatly appreciated! :)
Component TS
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<any>;
album: Observable<any>;
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) => {
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 => {
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 };
});
}
}
Component HTML
<h1> {{ (album | async)?.album_title }} </h1>
<div>
{{ (album | async)?.album_title }}
{{ (album | async)?.formattedDate }}
{{ (album | async)?.album_client }}
{{ (album | async)?.album_reference }}
</div>
UPDATE
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?
If anyone can let me know if this is a legitimate way of performing this action, that would be awesome :D
getProjectData() {
var db = firebase.firestore();
var docRef = db.collection(`folders/${this.folderId}/albums`).doc(`${this.albumId}`);
docRef.get().then((doc) => {
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;
}