stumbler
stumbler

Reputation: 747

from Firebase database retrieve details against a particular value using angular

In my demo application I have an 'Employee' interface which contains the below fields: employee.ts

export interface Employee{
    id:string;
    firstName:string;
    lastName:string;
    email:string;
    mobileNumber:string;

}

In the UI I am showing all the employee added in Firebase database. Now ,with the employee Id I want to update that employee's particular data. edit-employee.component.ts:

import { Component, OnInit } from '@angular/core';
import { Employee } from '../employee';
import { EmployeeService } from '../employee.service';
import { ActivatedRoute } from '@angular/router';

@Component({
  selector: 'app-edit-employee',
  templateUrl: './edit-employee.component.html',
  styleUrls: ['./edit-employee.component.css']
})
export class EditEmployeeComponent implements OnInit {
employee:Employee;
id:string;
submitted:boolean=false;
  constructor(private employeeService:EmployeeService,
    private activeRoute:ActivatedRoute) { }

  ngOnInit(): void {
    this.activeRoute.params.subscribe(
    (data)=>{
       this.id=data['id'] 
    }
    );
    console.log('id::'+this.id);
    this.employeeService.getEmployeeById(this.id).subscribe(
      (data)=>{
        console.log(data);
        this.employee=data.map((e)=>{
            return{
              firstName:e.payload.doc.data()['firstName'],
              lastName: e.payload.doc.data()['lastName']
            }
        })
        console.log(this.employee);
      }
    )
  }
  onSubmit(){
    console.log('submitted');
    this.submitted=true;
  }

}

employee.service.ts:

getEmployeeById(id:string):Observable<any>{
   //return this.firestore.collection('users').doc(id).valueChanges();
   return this.firestore.doc('users/'+id).get();
  }

I want to populate data against employee id selected from the UI. But I am getting an error to populate those data. enter image description here

enter image description here

Upvotes: 0

Views: 355

Answers (2)

Nayak
Nayak

Reputation: 762

Considering id is the Document ID of the object stored in Firestore. This will return an object.

return this.firestore.doc('users/'+id).valueChanges();

Else, if it's an attribute of the saved object, then you have to query in the collection. This will return an array of objects. Only 1, if the id is unique

return this.firestore.collection('users', ref => ref.where('id', '==', id)).valueChanges();

Log this data in the subscribe. It should be the exact object that you might have saved in the firestore.

ngOnInit(): void {
  this.activeRoute.params.subscribe(
    (data)=>{
      this.id = data['id'] 
      console.log('id::'+this.id);
      this.employeeService.getEmployeeById(this.id).subscribe(
       (data)=>{
         console.log(data); // Should be the exact same object that was saved.
         // Using the 2nd way, this will return an array with 1 item. So take the 0th element, ie data[0]
         this.employee = data; // data[0]
      });
    }
  );
}

Note: Always maintain Types to get the benefits of TypeScript.

Upvotes: 1

Barremian
Barremian

Reputation: 31135

The primary issue here is you're assuming this.id is assigned a value by the time you call this.employeeService.getEmployeeById(this.id). But this.id is assgined asynchronously. Though it might be assigned sometimes correctly, it can't be guaranteed to be everytime. In this case you could use one of RxJS higher order mapping operators like switchMap.

ngOnInit(): void {
  this.activeRoute.params.pipe(
    switchMap(data => {
      this.id = data['id'];
      console.log('id::'+this.id);
      return this.employeeService.getEmployeeById(this.id);
    })
  ).subscribe(
    data => {
      console.log(data);
      this.employee = data.map((e) => ({
        firstName:e.payload.doc.data()['firstName'],
        lastName: e.payload.doc.data()['lastName']
      }))
      console.log(this.employee);
    }
  );
}

This probably won't solve your issue. For that to work you need to make sure the data in the subscription is an array. If not, you can't invoke map function on it.

Upvotes: 0

Related Questions