1

I have a collection of artists. Some of those artist documents have an albums collection underneath which will have individual album documents. I'm trying to create a view in my html that displays each artist and their albums. However, I'm having a little difficulty building the array sufficiently. This is as far as I have got:

arrayForTemplate = [];

--

fetchArtists(){

 var albums_array = [];

 this.db.collection(`pathexample`).orderBy("order").get().then((querySnapshot) => {
    querySnapshot.forEach((artist) => {

      const artist_data = artist.data();
      const artist_id = artist.id;
      artist_data["id"] = artist_id;

      // Push the list of artists into the array
      this.arrayForTemplate.push(artist_data)

     this.db.collection(`pathexample/${artist_id}/albums`).orderBy("order").get().then((querySnapshot) => {
        querySnapshot.forEach((album) => {

          const album_data = album.data();
          const album_id = album.id;       
          
          // Push an array of albums into each artist 
          var album_information = {};
          album_information["album_photo"] = album_data.album_photo;
          album_information["album_date"] = album_data.album_date;

          albums_array.push(album_information)

        });

      });
    });    
})
.catch((error) => {
    console.log("Error getting documents: ", error);
});

}

  1. Array in my template
  2. Perform a query to get all artists
  3. Push the returned data into the array
  4. For each of the artists, query the albums collection based on the artist ID
  5. For each album, create an object with the data I wish to include in the array
  6. Update the albums_array with the new data

The question I now have is: How do I push all of this data into the arrayForTemplate array so that the data is structured like this: (Please let me know if this is bad practise or if there's a better away to achieve this)

  • Artist 1
  • Artist 2
    • [albums]
      • album photo
      • album date
  • Artist 3
    • [albums]
      • album photo
      • album date

The goal is to have the HTML as follows:

<div *ngFor="let artist of arrayForTemplate">
    <div> {{ artist.name }} </div>
    <div *ngFor="let album of artist.albums"> {{ album.album.photo }} </div>
</div>
2
  • can u provide what is the exact output of artist.data(); output of album.data(); Commented Jul 1, 2021 at 9:31
  • Hey @VENKATESHCHAVVAKULA - It's essentially any information in a document such as artist_name. I've just renamed the default firebase sdk const values, which would original be const data = doc.data() for example. Does that help? Commented Jul 1, 2021 at 9:43

1 Answer 1

0
Try this once
--
fetchArtists(){
    arrayForTemplate = [];
 this.db.collection(`pathexample`).orderBy("order").get().then((querySnapshot) => {
    querySnapshot.forEach(async (artist) => {
        let artist_data = artist.data();
        artist_data["id"] = artist.id;
        let albums = await this.getAlbums(artist.id)
        artist_data["albums"] = albums;
        arrayForTemplate(artist_data)
  });    
})
.catch((error) => {
    console.log("Error getting documents: ", error);
});
}
getAlbums(artist_id){
    let albums = []
    return new Promise((resolve, reject) => {
        this.db.collection(`pathexample/${artist_id}/albums`).orderBy("order").get().then((querySnapshot) => {
            for (let album of querySnapshot) {
                let album_data = album.data();
                album_data["id"] = album.id;
                // Push an array of albums into each artist 
                album_data["photo"] = album_data.album_photo;
                album_data["date"] = album_data.album_date;
                albums.push(album_data)
            }
            resolve(albums)
        }).catch((error) => {
            resolve([])
        });
    })

}

<div *ngFor="let artist of arrayForTemplate">
    <div> {{ artist.name }} </div>
    <div *ngFor="let album of artist.albums"> {{ album.photo }} </div>
</div>
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! - This is looking good! - The only issue found so far is that if a new artist is added and I return to this component, the array is no longer populated by the 'order' property. It's only correctly ordered on page refresh. I did however modify ` for (let album of querySnapshot) {` to ` querySnapshot.forEach(async (albums) => {` because it was throwing an error otherwise.

Your Answer

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