Search code examples
angulartypescriptgoogle-cloud-firestoreangularfire2

Alternative Syntax or Logic for AngularFireStore Update?


I would like to ask for alternative ways to implement Update data in firestore inside a component ts.

Normally I would use a service and subscribe thru it, however, subscribing and using the service became too laggy and our app crashes since our data team injected around 20k+ records due to data migration.

Normally I do the following the old way:


Via Service:


import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument} from '@angular/fire/compat/firestore';
import { Observable } from 'rxjs';
import {map } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})

export class CustomerService {
  customerCollection: AngularFirestoreCollection <Customer>;
  customerDoc: AngularFirestoreDocument <Customer>;
  customers: Observable<Customer[]>;

   constructor(
    public angularFireStore: AngularFirestore

  ) 
  {}

    getCustomer() {
    this.customerCollection = this.angularFireStore.collection('customer');
    this.customers = this.customerCollection.snapshotChanges().pipe(map(changes => {
      return changes.map( a => {
        const data = a.payload.doc.data() as Customer;
        data.id=a.payload.doc.id;
        return data;
      })

    }))
    return this.customers;
  }

  addCustomer(customerAdd:Customer) {
    this.customerCollection.add(customerAdd);
  };

  updateCustomer(custcol : Customer) {
    this.customerDoc = this.angularFireStore.doc(`customer/${custcol.id}`);
    this.customerDoc.update(custcol);
  }


}

Normally in my Component TS Old Code, I just usually put the update on a function like this.

 customerList: customerModel[];
 customerDetails : customerModel;
 customerName: any;
 
 addCustomer : Customer ={
    customerNo: '',
    customerAccountNo: '',
    customerName: '',
    customerAddress: '',
    customerContactNo: '',
    customerEmail: ''

  };

ngOnInit(): void {
 this.customerService.getCustomer().subscribe( customerObservable => {
 this.customerList = customerObservable});
}


add() {
 this.addCustomer.customerName = this.customerName //(input comes from ngModel btw)
 this.customerCollection.add(this.addCustomer);
}

update(){
 this.customerDetails.customerName = this.customerName //(input comes from ngModel btw)
 this.customerService.UpdateCustomer(this.customerDetails)
}

This works properly and smoothly when we only have 6000+ records, but as stated above after injecting additional records loading and even updating become laggy.

Searching thru solutions, we stop using the service, and put everything inside the component instead , I manage to implement the Query (but just ValueChanges, I believe in order to update I should use SnapshotChanges) and Adding, however there's very minimal or no documentation at all for the Update even on the official AngularFireStore Documentation, that's why I'm struggling for the correct syntax/logic for this one.

Here's my updated Component TS Code

import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from '@angular/fire/compat/firestore';
import { Observable} from 'rxjs'; 
import { Customer } from '../../models/customer.model';


@Component({
  selector: 'app-add-client',
  templateUrl: './add-client.component.html',
  styleUrls: ['./add-client.component.scss']
})
export class AddClientComponent implements OnInit {

 private customerCollection: AngularFirestoreCollection<Customer>
 private customerDocs: AngularFirestoreDocument<Customer>
 customers: Observable<Customer[]>
  
 constructor(
    public afs: AngularFirestore
  ) { 
    this.customerCollection = this.afs.collection<Customer>('customer')
    this.customers = this.customerCollection.valueChanges();
  }
 customerList: Customer[];
 customerDetails: Customer;

 addCustomer : Customer ={
    customerNo: '',
    customerAccountNo: '',
    customerName: '',
    customerAddress: '',
    customerContactNo: '',
    customerEmail: ''
 
  };

queryCustomer() {
    
    this.customerCollection = this.afs.collection('customer',
    ref => ref
    .orderBy('customerName')
    .startAt(this.query)
    .endAt(this.query + "\uf8ff"));
    this.customers = this.customerCollection.valueChanges();
    this.customers.subscribe(
     (data) => (this.customerList = (data)));
  }

add() {
  this.addCustomer.customerName = this.customerName;
  this.customerCollection.add(this.addCustomer);
}

queryCustomer() {
    
    this.customerCollection = this.afs.collection('customer',
    ref => ref
    .orderBy('customerName')
    .startAt(this.query)
    .endAt(this.query + "\uf8ff"));
    this.customers = this.customerCollection.snapshotChanges().pipe(map(changes =>{
        return changes.map(a =>{
        const data=a.payload.doc.data() as depositModel;
        data.id=a.payload.doc.id;
        return data;
       });
      }
    ));
    this.customers.subscribe(
     (data) => (this.customerList = (data)));
  }


}

I did the following attempts, but somehow they don't work


update() {
 
  this.customerDocs = this.angularFirestore.doc(`jobOrders/${customerDetails.id}`);
  this.customerDocs.Update(customerDetails);

}


I'm really new to this kind of implementation and hopefully, someone could help me on this one. Thank you.


Solution

  • As mentioned in the example1 and example2, update can be done as :

    Example1 :

    onRename() {
            if (!this.editForm.value.replaceValue) {
                this.message = "Cannot Be Empty!";
            } else {
                this.firestore.collection('testCollection').doc(this.id).update({ field: this.editForm.value.replaceValue });
                this.edit = false;
                this.message2 = '';
                this.single = null;
            }
        }
    

    Example2 :

    updateCoffeeOrder(data) {
       return
           this.firestore
           .collection("coffeeOrders")
           .doc(data.payload.doc.id)
           .set({ completed: true }, { merge: true });
    }
    

    You can refer to the stackoverflow thread and video on CRUD operations.