Les Paul
Les Paul

Reputation: 1278

Rewrite code to have BehaviorSubject subscribe with Observable

I am learning Angular2 and RxJS and I'm following someone else's application. In his application, he has two modules. The first is the asObservable.ts file:

asObservable.ts

export function asObservable(subject: Subject) {
    return new Observable(fn => subject.subscribe(fn));
}

The second is a file that creates a new BehaviorSubject RxJS object and sends it to the asObservable.ts module

todo-store.service.ts

import {asObservable} from "./asObservable";
import {List} from "immutable";
import {Todo} from "./todo";
// Todo is a customized class

@Injectable()
export class TodoStore {

    private _todos: BehaviorSubject<List<Todo>> = new BehaviorSubject(List([]));

    get todos() {
        return asObservable(this._todos);
    }

    loadInitialData() {
        this.todoBackendService.getAllTodos()
            .subscribe(
                res => {
                    let todos = (<Object[]>res.json()).map((todo: any) =>
                        new Todo({id:todo.id, description:todo.description, completed: todo.completed}));
                    this._todos.next(List(todos));
                },
                err => console.log("Error retrieving Todos")
            )
    }
    //unnecessary code omitted
 }

I would like to eliminate the asObservable.ts file and perform the subscribe function in a single function but I can't figure out how it would be done, something like:

get todos() {
    return new Observable(Subject.subscribe(this._todos));
}

This obviously doesn't work. Could someone give me some pointers on the proper way to do this and a brief explanation of what I am doing wrong?

Upvotes: 1

Views: 1146

Answers (1)

martin
martin

Reputation: 96889

It seems to me that the original author didn't know there's already asObservable() method. However, his version that requires a Subject doesn't make sense to me, it's just a complicated way to do a very simple thing. Also, this way you can't unsubscribe.

I'd instead stick to the original asObservable(). Its purpose is to hide the fact that you're using a Subject internally and you can expose just an Observable:

export class TodoStore {
    // ...
    observable: Observable;

    constructor() {
        this.observable = this._todos.asObservable();
    }
}

Then subscribing works like anywhere else:

let store = // ... TodoStore from DI or whatever
store.observable.subscribe(val => console.log(val));

Upvotes: 3

Related Questions