angularservicecallbackobservablesubject

Angular observable is not working in callback funtion but Subject is working


I have a callback method in a service which have code like below:

@Injectable({
  providedIn: 'root'
})
export class AService {

counter: number = 0;
anObject = new anObject();

dataObservable = {} as Observable<anObject>;

dataSubject = new Subject<anObject>();

aMethod = () => {
    this.anObject.a += 4;
    this.anObject.b += 3;

    //- With subject, works fine and I can use anObject's data in component
    this.dataSubject.next(this.abObject);     

    //- but when I try with observable, it doesn't work
    this.dataObservable = new Observable((observer) => observer.next(this.anObject));
   
   this.counter++;
   
   if (this.counter < 100 ) {
    this.aMethod;
  }
}

In short, I have a method in service which will run 100 times and will update value with every 100 ms in component, however this works fine with 'Subject' but doesn't work with 'Observable'.

I don't like to use 'Subject' here, because there is only single subscriber, which will use the service.

Thanks in advance of any suggestion..


Solution

  • I don't think you can use Observable in this way

    this.dataObservable = new Observable((observer) => observer.next(this.anObject));
    

    because at this line you are recreating an observable instance each time and assigning it to the same property, and so if you have any subscribers to this property they won't receive a data, becasause they were subscribed to a different instance of Observable object.

    What you need to do is to create your Observable once, and then call observer.next each time when there is a new data.

    From your example I think it would be quite difficult to achieve that, using Subject here looks more convenient.

    If you worry about making the Subject property public, you can use asObservable on your subject to create an observable, and so in this case you will have a private subject that is convenient to use, but in the public API you will have only Observable.

    private dataSubject = new Subject<anObject>();
    public dataObservable = dataSubject.asObservable();