3

What I'm using

  • Angular
  • Firestore

What I'm trying to achieve

  • Manipulate document data

  • Convert the returned date into something readable

What I have

  • I have a list of albums where i use snapshotChanges to return the mapped data

  • I have an album that's a AngularFirestorDocument

Questions

  • How can i manipulate the returned date in my album component the same way I have in the albums list component?

Album List

So this component brings back a list of albums correctly, and I can manipulate the date before i return it so that the HTML displays the correct format.

export class AlbumsListCompoment implements OnInit {

  private albumCollection: AngularFirestoreCollection<any>;
  albumns: Observable<any[]>;
  folderId: string;

  constructor(
    private readonly afs: AngularFirestore,
    private activatedRoute: ActivatedRoute,
    private router: Router
  ) {

    // Look at the url for the Folder ID and set the local variable
    this.activatedRoute.params.forEach((urlParameters) => {
      this.folderId = urlParameters['folderId'];
    });

    // Album Reference "folders/folderid/albums"
    this.albumCollection = afs.collection<any>(`folders/${this.folderId}/albums`);

    // Get the data
    this.albumns = this.albumCollection.snapshotChanges().map(actions => {
      return actions.map(a => {

        const data = a.payload.doc.data();

        // Get the date from each album
        var albumDateTimeStapm = data.album_date;

        // Convert the unix value and format it based on the users locale setting
        var albumDateISO = moment(albumDateTimeStapm).format("DD/MM/YYYY");

        // Create a new 'name' to use in the HTML binding
        data.formattedDate = albumDateISO;

        const id = a.payload.doc.id;
        return { id, ...data };
        });
       });
      }

  ngOnInit() {

  }

  }

Album

I'm not entirely show how to approach this component to perform the same manipulation. It isn't a list, it's a single document / album.

export class AlbumDetails implements OnInit {

  folderId: string;
  albumId: string;

  private albumDoc: AngularFirestoreDocument<any>;
  album: Observable<any>;

  constructor(
    private readonly afs: AngularFirestore,
    private activatedRoute: ActivatedRoute,
    private router: Router) {

    // 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'];
    });

    this.albumDoc = afs.doc<any>(`folders/${this.folderId}/albums/${this.albumId}`);
    this.album = this.albumDoc.valueChanges();


  }

  ngOnInit() {}

}

Any help would be greatly appreciated :)

1 Answer 1

3

I am not 100% sure that I understand your question. From what I understand you would like to get a handle on the returned data of the document and then change that before you display on HTML.

If that is the case you can do the following:

this.albumDoc = afs.doc<any>(`folders/${this.folderId}/albums/${this.albumId}`);
this.album = this.albumDoc.valueChanges();
this.album.subscribe(value => {
  const value1 = value.value1;
  const value2 = value.value2;
  ...
  const valueN = value.valueN;
});

If you also need metadata of the returned value (such as the id) then do the following:

this.albumDoc = afs.doc<any>
(`folders/${this.folderId}/albums/${this.albumId}`);
  this.album = this.albumDoc.snapshotChanges();
  this.album.subscribe(value => {
    const id = value.payload.id;
    const value1 = value.payload.data().value1;
    const value2 = value.payload.data().value2;
    ...
    const valueN = value.payload.data().valueN;
});

for more information on this see angularfire2 documentation

Sign up to request clarification or add additional context in comments.

8 Comments

Hi Chris! This is so close. How would I obtain the ID for the returned album?
@MegaTron I have updated my answer to include the answer to the case in your comment. If my answer works for you will you please mark as accepted.
Hi Chris. Thank you so much for the response. I'm new to this so it's the subscribe part that's really helped me out. One last thing in regards to your last post, how would I databind 'value1' to my html? Again, thank you. I will most certainly mark this as the answer.
@MegaTron It is a pleasure. There is a few ways to do that. One way would be do declare a property in your AlbumDetails component and to bind the property name through interpolation. So you would declare say value1: string; in your component then set this.value1 = value.payload.data().value1; Then you will for example have <h1>{{value1}}</h1> in you html. See angular.io/guide/displaying-data for more details.
I have tested quickly, it does work. Are you declaring the value1: string; at global scope for the component. So below the export class AlbumDetails ....
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.