why is each hot observable called observable?

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.

Leave a Comment

Your email address will not be published.

Scroll to Top