RxJS Subjects and Angular 2 components

I am coming to terms with the fact that web development is changing and I need to get to grips with RxJS. I am currently developing a web app using Angular 2.0.0-beta.15.

I am following the most excellent ng-book 2 (is that kind of advertising allowed? Oh well). It covers in broad, shallow strokes some important concepts in RxJS and provides links to further reading. I have read and understood the source code and accompanying explanation, but am left a little in the dark about some details regarding Subjects in particular and how Angular 2 components consume these Subject streams.

I have augmented the code from the book thusly:

export class SubmitResourceComponent {
    private _newResourceTags: Subject<Tag> = new Subject<Tag>();
    private _resourceTags: Observable<Tag[]>;
    private _tagUpdates: Subject<any> = new Subject<any>();
    private _create: Subject<Tag> = new Subject<Tag>();
    private _remove: Subject<Tag> = new Subject<Tag>();

    constructor() {
        this._resourceTags = this._tagUpdates
            .scan((tags: Tag[], operation: ITagsOperation) => operation(tags), initialTags);

        this._create
            .map((tag: Tag): ITagsOperation => (tags: Tag[]) => _.uniq(tags.concat(tag)))
            .subscribe(this._tagUpdates);

        this._remove
            .map((tag: Tag): ITagsOperation => (tags: Tag[]) => _.without(tags, tag))
            .subscribe(this._tagUpdates);

        this._newResourceTags.subscribe(this._create);
    }

    get resourceTags(): Observable<Tag[]> {
        return this._resourceTags;
    } 

    protected addTagToResource(tag: Tag): void {
        this._create.next(tag);
    }

    protected removeTagFromResource(tag: Tag): void {
        this._remove.next(tag);
    }
}

And I am consuming the _resourceTags like this:

<button class="btn" *ngFor="#tag of resourceTags | async" (click)="removeTagFromResource(tag)">{{ tag.name }}</button>

What I can’t grasp, even with excellent support from the gitter forums, is why the UI displays all of the tags that are pushed into the _resourceTags Subject. I would imagine that the stream is like a rubber pipe: once an element has been pushed into the Subject and published to whatever Observer (in this case, the UI element), does it not then evaporate and disappear? Does it stay in the stream/pipe/Subject? How is the UI element subscribing to the Subject? Am I thinking about it in the wrong way? Do I need a complete mental restructuring/transplant?

So many questions!

2
Leave a Reply

avatar
2 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
1 Comment authors
Jason Recent comment authors
  Subscribe  
newest oldest most voted
Notify of
Jason
Guest

Data passed to next is like an event. The subscriber gets the value and the Observable created by the Subject doesn’t hold any reference to it (except you use special operators with the purpose to buffer or by other means keep emitted values. With | async Angular subscribes to the Observable (Subject) and when it receives a value it displays it. *ngFor only renders arrays. If you want use *ngFor with Subject, the subject needs to emit arrays – each event is not a single value but an array of values and these values are rendered by *ngFor and replaced… Read more »

Jason
Guest

I think observables store values of a variable in the browser memory only until the session is cleared, just like how you would set up a variable to get a value from an input box and upon hitting refresh on the browser the values is emptied. In the above scenario i would think like most SPAs the browser is prevented from default behavior of refresh/reload and you get some sort of persistence so when you do an operation like ... _.uniq(tags.concat(tag))).subscribe(this._tagUpdates);... the values continue to pile up as they’re concated by the create event but would disappear when a manual… Read more »