I’m working on an Angular service that fetches rules from a secondary cart and updates a BehaviorSubject to manage the state. However, my subscribers are not receiving updates even after the state is updated.
Here is the code for my service:
import { Injectable, NgZone, Injector } from '@angular/core';
import { Observable, of, BehaviorSubject } from 'rxjs';
import { debounceTime, filter, switchMap, map, shareReplay } from 'rxjs/operators';
import { cloneDeep, get, isNil, filter as _filter, concat, isEmpty } from 'lodash';
import { SecondaryCartService } from './secondary-cart.service';
import { AppliedRuleActionInfo } from './applied-rule-action-info';
@Injectable({
providedIn: 'root'
})
export class YourService {
private secondaryCartService: SecondaryCartService = this.injector.get(SecondaryCartService);
private state: BehaviorSubject<Array<AppliedRuleActionInfo>> = new BehaviorSubject<Array<AppliedRuleActionInfo>>(null);
private ngZone = this.injector.get(NgZone);
fetchRule(): Observable<Array<AppliedRuleActionInfo>> {
return this.secondaryCartService.getMyCart()
.pipe(
debounceTime(2000),
filter(cart => cart && !cart.IsPricePending),
switchMap(cart => {
if (!(get(cart, 'LineItems')?.length)) {
return of(null);
}
return of(get(cart, 'AppliedRuleActionInfo'));
}),
map((rules) => {
const currentState = this.state.value;
if (!this.compareRules(currentState, rules) || !this.compareRules(rules, currentState) || isNil(rules)) {
this.ngZone.run(() => this.state.next(cloneDeep(rules)));
}
return rules;
}),
shareReplay(1)
);
}
getState(): Observable<Array<AppliedRuleActionInfo>> {
return this.state.asObservable();
}
getAcion(): Observable<Array<AppliedRuleActionInfo>> {
return this.getState().pipe(
map(actions => {
let filteredAppliedRuleAction = _filter(actions, action => action.Pending === true && !isEmpty(concat(get(action, 'ActionProductIds'))));
return filteredAppliedRuleAction;
})
);
}
}
Problem:
Even though this.state.next(cloneDeep(rules)) is called within the service, the getPendingActionsForCart method’s subscribers are not receiving the updated state. I expect that whenever the state is updated, the subscribers of getPendingActionsForCart should receive the new state with the pending actions.
What I Have Tried:
Verified that this.state.next(cloneDeep(rules)) is indeed being called.
Ensured this.state is a BehaviorSubject and initialized properly.
Checked that the observable returned by getState() is being subscribed to correctly.
Additional Information:
The comparison logic in compareRules is just a simple JSON string comparison for now.
fetchRulesFromSecondaryCart is being called, and the state is supposed to be updated within the map operator.