3

I am trying to merge/join the data from two separate collections in Firestore. The data model I have looks as following:

customers--+
           |
           +--<generatedId>+
           |               +-- fullName
           |               +-- phone
           |
           +--<generatedId>+
                           +-- fullName
                           +-- phone

tasks------+
           |
           +--<generatedId>+
           |               +-- dateCreated
           |               +-- customerId 
           |
           +--<generatedId>+
                           +-- dateCreated
                           +-- customerId

Note: customerId is the document id in the customers collection

tasks.component.ts:

import { Component, OnInit } from '@angular/core';
import { TasksService } from '../tasks.service';
import { Observable } from 'rxjs/Observable';

@Component({
  selector: 'app-tasks',
  templateUrl: './tasks.component.html',
  styleUrls: ['./tasks.component.css']
})

export class TasksComponent implements OnInit {

  tasks: any[];

  constructor(private _tasksService: TasksService) { }

  ngOnInit() {
    this._tasksService.getTasks().subscribe(tasks => {
      const taskArr = [];
      tasks.forEach(element => {
        const customer = this._tasksService.getCustomer(element.data.customerId);
        taskArr.push({
          id: element.id,
          data: element.data,
          cus: customer
        });
      });
      this.tasks = taskArr;
    });

}

task.service.ts:

import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from 'angularfire2/firestore';

@Injectable()
export class TasksService {

  tasksCollection: AngularFirestoreCollection<any>;
  customerDocument: AngularFirestoreDocument<any>;

  constructor(public afs: AngularFirestore) {
  }

  getTasks() {

    /* Returns list of the tasks */

    this.tasksCollection = this.afs.collection<any>('tasks');
    return this.tasksCollection.snapshotChanges().map(actions => {
      return actions.map(a => {
        const data = a.payload.doc.data();
        const id = a.payload.doc.id;
        return { id, data };
      });
    });
  }

  getCustomer(id: string) {

    / * Returns customer information details */

    this.customerDocument = this.afs.doc<any>('customers/' + id);
    return this.customerDocument.valueChanges();
  }
}

app.component.html:

  <ul *ngFor="let task of tasks">
    <li>
      {{task.id}} 
      {{task.data.dateCreated | date:'M/dd/yyyy, HH:mm a'}}
      {{(task.cus | async)?.fullName}}
      {{(task.cus | async)?.phone}}) 
    </li>
  </ul>

I have a feeling that this code is not optimal and correct although it works. Would you be able please to share your advices how I could have done this better?

Harvey Dent
  • 2,033
  • 2
  • 11
  • 7

0 Answers0