Your concept is wrong.
- You never unsubscribe! So you create memory leak many times as you call checkAll.
- Not need subject clone/copy.
interface IEvent {
checked_export: boolean;
}
export class EventService {
private events$: BehaviorSubject<IEvent[]> = new BehaviorSubject<IEvent[]>([]);
public next(events: IEvent[]): void {
this.events$.next(events);
}
public checkAll(): Observable<IEvent[]> {
return this.events$.pipe(
map((events: IEvent[]) => {
return events.filter((event: IEvent) => event.checked_export);
}),
);
}
}
// subscribe with async pipe: <ng-container *ngIf="data$ | async; else nodata">
// subscribe with async pipe: <ng-container *ngIf="isEmpty$ | async">
export class Component {
nodata: any;
constructor(private service: EventService) {
}
get data$(): Observable<IEvent[]> {
return this.service.checkAll();
}
get isEmpty$(): Observable<boolean> {
return this.data$.pipe(map((data) => data.length === 0));
}
}
Update for comment
@Injectable() // config into module's provider!!!
export class DataFromServerResolve implements Resolve<IEvent[]> {
constructor(private http: HttpClient) {
}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<IEvent[]> {
return this.http.get<IEvent[]>('url'); // then navigate here this resolving all time. Or use Ngrx Store / service to cache
}
}
// to routing
const routes: Routes = [{ path: '', component: MyComponent, resolve: { myData: DataFromServerResolve } }];
interface IEvent {
checked_export: boolean;
}
// subscribe with async pipe: <ng-container *ngIf="checkAll() | async; else nodata">
// subscribe with async pipe: <ng-container *ngIf="isEmpty$ | async">
@Component({
selector: '...',
templateUrl: '...',
styleUrls: ['...'],
})
export class MyComponent implements OnInit {
data: BehaviorSubject<IEvent[]>;
constructor(private route: ActivatedRoute) {
}
ngOnInit(): void {
// resolve: { myData: DataFromServerResolve } -> snapshot.data.myData (It will normal: IEvent[] type)
this.data = new BehaviorSubject<IEvent[]>(this.route.snapshot.data.myData);
}
// There is not ngDestroy to unsubscribe because "| async" will unsubscribe.
// If we use .subscribe(...) and save to variable then have to!
get isEmpty$(): Observable<boolean> {
return this.checkAll().pipe(map((data) => data.length === 0));
}
public next(newData: IEvent[]): void {
this.data.next(newData); // it will trigger all subscribers again
}
// or put service and make input parameter and "this.data" replace by parameter name
public checkAll(): Observable<IEvent[]> {
return this.data.pipe(
map((events: IEvent[]) => {
return events.filter((event: IEvent) => event.checked_export);
}),
);
}
}
CLICK HERE to find out more related problems solutions.