I have a firestore collection called Collectors and I'm interacting with it via angularfire. I'm able to subscribe and filtered from it to get the documents on it especially the collectorBillNo (please refer to the image), however, I'm stuck on the part where I need to increment the value of the collectorBillNo by 1 and update the document when I call a savePayment function.
Service Component:
import { Injectable } from '@angular/core';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument} from '@angular/fire/compat/firestore';
import { Observable } from 'rxjs';
import {map } from 'rxjs/operators';
import { teller } from '../models/tellermodel';
export class CustomerService {
tellerCollections: AngularFirestoreCollection <teller>;
tellerDoc: AngularFirestoreDocument <teller>;
tellers: Observable<teller[]>;
constructor(
public angularFireStore: AngularFirestore
)
{}
getTeller() {
this.tellerCollections = this.angularFireStore.collection('collector');
this.tellers = this.tellerCollections.snapshotChanges().pipe(map(changes => {
return changes.map( a => {
const data = a.payload.doc.data() as teller;
data.id=a.payload.doc.id;
return data;
})
}))
return this.tellers
updateTeller( updateCol: teller) {
this.tellerDoc = this.angularFireStore.doc(`collector/${updateCol.id}`);
this.tellerDoc.update(updateCol);
}
}
HTML doing the filtering part
<div >
<label>Teller Name: </label>
<select
required
name="tellerName"
(change)="loadBilling($any($event.target).value)"
id="collector"
[(ngModel)]="updateLedger.collectorName">
<option
class ="teller-class"
value="{{tellerList.collectorName}}"
*ngFor ="let tellerList of tellerList"
>
{{tellerList.collectorName}}
</option>
</select>
</div>
Component ts
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { CustomerService } from 'src/app/services/customer.service'; // Service Component
import { teller } from 'src/app/models/tellermodel'; // Model
import { MatTableDataSource } from '@angular/material/table';
@Component({
selector: 'app-teller',
templateUrl: './teller.component.html',
styleUrls: ['./teller.component.scss']
})
export class TellerComponent implements OnInit {
constructor(
private customerService: CustomerService, // Calls the AngularFire Service
) { }
// Declarations goes Here
tellerList: teller[]; // loads the collection as observable
dataTellerSource: MatTableDataSource<any>; // for filtering
billNo: any; // this is where the collectorBillNo will be stored upon filtering
ngOnInit(): void {
//Subscribe to the collection
this.customerService.getTeller().subscribe(telObs => {
this.tellerList = telObs; // Subsribes as an Observable
this.dataTellerSource = new MatTableDataSource(telObs); // loads the observable as DataSource
})
loadBilling(collector:string) { // performs the filter from the HTML method
// using MatTableDatesource filter, I can able to filter the specific document,
get its collectorBillNo
this.collectorName = collector;
this.dataTellerSource.filter = collector.trim().toLowerCase();
this.billNo = this.dataTellerSource.filteredData
.map (bn => bn.collectorBillNo)
.reduce ((acc,cur) => acc cur,0); // this gets the collectBillNo
savePayment() // it should update the document and increment the collectorCode by 1
this.billNo = this.billNo 1
/// I don't know what to do next here for it to be able to save from its respective document
}
}
CodePudding user response:
Bind the entire object to each option in the HTML, using ngValue. The selected object will be attached to the ngModel variable of the select element.
It seems you bound ngModel to updateLedger.collectorName which I don't see in the component, so I'll make a new variable called selectedTeller.
<div >
<label>Teller Name: </label>
<select
required
name="tellerName"
id="collector"
[(ngModel)]="selectedTeller">
<option
class ="teller-class"
*ngFor ="let teller of tellerList"
[ngValue]="teller"
>
{{teller.collectorName}}
</option>
</select>
</div>
Notice I've removed the (change) event, since angular will update the selected object automatically.
So your component will look like this
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
import { CustomerService } from 'src/app/services/customer.service'; // Service Component
import { teller } from 'src/app/models/tellermodel'; // Model
import { MatTableDataSource } from '@angular/material/table';
@Component({
selector: 'app-teller',
templateUrl: './teller.component.html',
styleUrls: ['./teller.component.scss']
})
export class TellerComponent implements OnInit {
constructor(
private customerService: CustomerService, // Calls the AngularFire Service
) { }
// Declarations goes Here
tellerList: teller[]; // loads the collection as observable
dataTellerSource: MatTableDataSource<any>; // for filtering
billNo: any; // this is where the collectorBillNo will be stored upon filtering
selectedTeller: teller;
ngOnInit(): void {
//Subscribe to the collection
this.customerService.getTeller().subscribe(telObs => {
this.tellerList = telObs; // Subsribes as an Observable
this.dataTellerSource = new MatTableDataSource(telObs); // loads the observable as DataSource
})
savePayment() {
this.customerService.updateTeller({ ...this.selectedTeller, collectorBillNo: this.selectedTeller.collectorBillNo 1 });
}
}

