Search code examples
angularbehaviorsubject

Behavior subject is not behaving properly?


I'm trying to follow the data table example out there, but have one issue when I'm trying to implement my datasource. The final subscribe is telling me I need to have data type of any in my behavior subject when I already have declared the type to be any.

And here is the aircraft-info service:

import { Aircraft } from '../shared/aircraft';
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';


@Injectable({
  providedIn: 'root'
})
export class AircraftInfoService {
  aircraft: Aircraft[];
  getApi = 'https://<domainRemoved>/api/PApps_AircraftInfo?<keyRemove>';

  constructor(private httpClient: HttpClient) { 

  }

  ngOnInit() {
    console.log('aircraftInfoservice');
  }

  getAircraft() {
    return this.httpClient.get(this.getApi)
  }
}

Here is the datasource code:

import { Aircraft } from '../shared/aircraft';
import { AircraftInfoService } from './aircraft-info.service';
import { BehaviorSubject } from 'rxjs';
import { CollectionViewer, DataSource } from '@angular/cdk/collections';
import { Observable } from 'rxjs';
import { of } from 'rxjs';
import { catchError, finalize } from 'rxjs/operators';

export class allAircraftInfoDataSource implements DataSource<Aircraft> {

  private aircraftDBSubject = new BehaviorSubject<any[]>([]);
  private loadingSubject = new BehaviorSubject<boolean>(false);

  public loading$ = this.loadingSubject.asObservable();

  constructor(private aircraftInfoService: AircraftInfoService) {}

  connect(collectionViewer: CollectionViewer): Observable<Aircraft[]> {
      return this.aircraftDBSubject.asObservable();
  }

  disconnect(collectionViewer: CollectionViewer): void {
      this.aircraftDBSubject.complete();
      this.loadingSubject.complete();
  }

  getAircraft() {

      this.loadingSubject.next(true);

      this.aircraftInfoService.getAircraft().pipe(
        catchError(() => of([])),
        finalize(() => this.loadingSubject.next(false))
      )
      .subscribe(data => this.aircraftDBSubject.next(data));      
  }    
}

The .next(data) is giving me the error:

ERROR in ../../src/app/services/aircraft-info-datasource.service.ts(36,56): error TS2345: Argument of type 'Object | any[]' is not assignable to parameter of type 'any[]'. The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead? Type 'Object' is missing the following properties from type 'any[]': length, pop, push, concat, and 26 more.

Editing question and including more information. The aircraft-info service is where the getAircraft call is contained. It is returning an httpclient get, so this is where the type of 'any' requirement is coming from. Since it's an http call, I can't type that, can I? If I try, it gives me errors. Is there the ability to cast a value in typescript like there is in 'C'?

Thanks....


Solution

  • Figured out I need to type the return from the http get in my subscribe call. Now have .subscribe((data:any[]) => this.aircraftDBSubject.next(data)); and everything works like a charm. WooHoo!