Reputation: 1153
I'm a little bit confused as why the following snipped works as expected. The idea of this service is to have a list of strings where if you add a string, it is removed 5 seconds later. Rxjs is used here:
@Injectable()
export class ErrorService {
private errors: Array<string> = [];
private emitErrorsChanged = new Subject<any>();
public emitErrorsChanged$ = this.emitErrorsChanged.asObservable();
constructor() {
this.emitErrorsChanged$.delay(5000).subscribe(
() => {
if (this.errors.length > 0) {
this.errors.shift();
}
}
);
}
public emitErrorChange(error: string) {
this.errors.push(`${error}`);
this.emitErrorsChanged.next(this.errors);
}
}
An error component is subscribed to this service errorService.emitErrorsChanged$.subscribe(...)
and shows the strings in a list. Other components/services add strings by this.errorService.emitErrorChange(error.message)
.
My question is: why are the removed errors (5s) emitted to the error component? The errors are just removed from the list
this.errors.shift();
but the change is not emitted bythis.emitErrorsChanged.next(this.errors);
Upvotes: 0
Views: 75
Reputation: 9232
The behavior occurs because you are passing reference to your object (list in this case). The changes made by this.errors.shift();
are not emitted, but I guess you can see current state of this.errors
thanks to Angular's change detection. I have prepared a demo (click) so you can see that the object reference is passed in your case - what means that the list in subscription is the exactly same array
list. To prevent it you can pass a copy of your list, e.g. using spread operator like in this example:
this.emitErrorsChanged.next([...this.errors]);
Upvotes: 1