Home > Software design >  Angular BehaviorSubject undefined at initialized
Angular BehaviorSubject undefined at initialized

Time:08-02

I'm trying to create a new BehaviorSubject of type ICar (defined by me) in a service and put null or undefined by default. If I'm updating the type to ICar | undefined, I will get an error at function getCar() because is complaining about the return type. Is there any workaround to resolve this issue?

My code:

export interface ICar{
 id:number,
 name: string,
}
//service:
@Injectable({
    providedIn: 'root'
})
export class CarService {
    private car$ = new BehaviorSubject<ICar>(null); //error

    constructor() {
    }

    setCar(car: ICar) {
        this.car$.next(car);
    }

    getCar(): Observable<ICar> {
        return this.car$;
    }
}

CodePudding user response:

If your car$ can be null only at the beginning, and you need behaviorSubject only to store the previously loaded value, you can use something like:

private carSubject = new BehaviorSubject<ICar>(null);
private car$ = carSubject.pipe(filter(car => !!car) car is ICar);

in this filter operator, you are filtering all nullish values and after that saying that car is of type ICar.

And, just as a suggestion to think about: maybe it will be better to make a small rewrite of this service. For example, you can prevent changing values of the subject from outside (current implementation will pass a reference to a subject out from the service).

Maybe to something like that:

class CarService implements OnDestroy {
  private readonly car = new BehaviorSubject<ICar | null>(null);

  // from the property below you can get your subject values but as 
  // an observable, so it will be closed for .next from outside
  readonly car$ = car.pipe(filter(car => !!car) car is ICar);

  ngOnDestroy(): void {
    this.car.complete(); // <- do not forget to close your subject;
  }

  setCar(car: ICar): void {
    this.car.next(car);
  }
}

CodePudding user response:

If you open your tsoconfig.ts you could add property "strictNullChecks": false,. Although I don't know if it is wise thing to do.

https://www.typescriptlang.org/tsconfig#strictNullChecks

The real solution would be to simply say that the value/type can be empty, ICar | null

OR

You can use Subject instead of a BehaviourSubject and publish only valid ICar to that stram

  • Related