Please help me to fix an issue I'm struggling.
I have an array of Firebase object keys
const keys = ['-Kx9pqoMWlJLbKLQcAkP', '-Kx9pqoOYlDHTJ64Was5']
What I'm trying to do is to get all those Firebase objects in one stream using forkJoin
. Here's what I have:
const obj1 = this.fbService.getObj(keys[0]);
const obj2 = this.fbService.getObj(keys[1]);
forkJoin([obj1, obj2])
.subscribe(res => {
console.log(res); // <-- this never happens
};
fbService method is:
getObj(key): Observable<MyObj> {
return this.fb.object(`/path/to/obj/${key}`).valueChanges();
}
I assume that this getObj
method doesn't work well with forkJoin
, maybe because of valueChanges
, am I using it correctly?
However:
getObj
works fine for getting single Firebase object, like:
this.fbService.getObj(keys[0])
.subsribe(res => console.log(res))// <-- works
forkJoin
works fine with simple HTTP requests, like
const r1 = this.http.get('https://swapi.co/api/people/1');
forkJoin([r1])
.subscribe(res => {
console.log(res); // <-- works
};
So, what am I doing wrong? My goal is to get array of objects from array of keys:
['-Kx9pqoMWlJLbKLQcAkP', '-Kx9pqoOYlDHTJ64Was5'] => [{prop:'val'},{prop:'val2'}]
forkJoin accepts a variable number of observables and subscribes to them in parallel. When all of the provided observables complete, forkJoin collects the last emitted value from each and emits them as an array (this is by default, more on this later).
forkJoin will wait for all passed observables to emit and complete and then it will emit an array or an object with last values from corresponding observables.
The ValueChanges is an event raised by the Angular forms whenever the value of the FormControl, FormGroup or FormArray changes. It returns an observable so that you can subscribe to it. The observable gets the latest value of the control. It allows us to track changes made to the value in real-time and respond to it.
The forkJoin
operator requires all source Observables to emit at least one item and to complete.
I don't know much about firebase but I'm suspicious that valueChanges
never completes so that's why forkJoin
never emits anything. One way to work with this is using take(1)
to always complete the chain.
forkJoin(obj1.take(1), obj2.take(1)).subscribe(res => console.log(res);
Maybe in your case it would be better to use zip()
operator that just requires all source Observables to emit the same number of items. However make sure you unsubscribe it because it doesn't complete itself until its source Observables complete.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With