简体   繁体   中英

Combining firebase observables with angular2

I'm working on an angular2 - firebase app, and was wondering on some best rxjs practices, that I find difficult to google.

Say I have a class "Project" with properties like "name", "$key", etc. And then also arrays of "Note[]" and "Task[]"

"Note" and "Task" are then their own classes.

Initially I structured data in firebase like this:

  • Project
    • Name
    • Tags
    • Other meta stuff
    • Tasks
      • Task1
      • Task2, etc
    • Notes
      • Note1
      • Note2, etc

I would get one data stream and use map to get the data to look exactly how I want it.

But then I realised that this is bad practice and the project trees should be as flat as possible so that I wouldn't be forced to load everything when I just need the project metadata for example.

So I restructured it to be like this:

  • Projects
    • Project1
      • Name
      • Tags
      • etc
    • Project2
      • Name
      • Tags
      • etc
  • Tasks
    • Project1
      • Task1
        • Name
        • Body
      • Task2
        • Name
        • Body
    • Project2
      • Task1
        • Name
        • Body
      • Task2
        • Name
        • Body
  • Notes
    • Project1
      • Note1
        • Name
        • Body
      • Note2
        • Name
        • Body

So this way I get three data streams of "Projects" "Notes" and "Tasks". It seems to make sense to combine this into a single stream of "Projects" with "Notes" and "Tasks" inside it.

Although I'm unsure of what's the best way to do that? I wrote a long function that concatMaps everything into and array of "Project[]", but now I'm left with an array instead of a stream, which definitely seams wrong.

Or maybe it's a wrong approach altogether?

Looking forward to your thoughts. Thanks! H

I don't understand your structure exactly but if you have "Projects" "Notes" and "Tasks" as three separate streams (I guess this means you have three Observables). You can use merge() or concat() to consume whichever values comes first from any of them or consume one Observable at the time respectively:

let obs1 = Observable.from([1, 2, 3]).map(v => Observable.of(v).delay(1000)).concatAll();
let obs2 = Observable.from(['a', 'b', 'c']).map(v => Observable.of(v).delay(1000)).concatAll();

obs1.concat(obs2)
  .subscribe(v => console.log(v));

obs1.merge(obs2)
  .subscribe(v => console.log(v));

See live demo: http://plnkr.co/edit/TLxg1jOuhAN6U8xoQJIo?p=preview

The first example with concat() prints:

1
2
3
a
b
c

The second example with merge() gives:

1
a
2
b
3
c

I think you should understand the difference.

Don't mind the complicated operator chaing for obs1 and obs2 . It's just to emit each value with delay to simulate asynchronous streams.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM