angular-meteor
angular-meteor copied to clipboard
Different subscription behaviour for mongo collections
If was playing with my subscription of a mongo collection, doing search on a third party api that resulted in inserting records in my mongo collection. However, I noticed that I didn't see my subscription working in my template when I trigger the mongo insert while using one method, but it did work with another method.
Again for me this is confusing, what is the best practice and/or is this behaviour on purpose?
This subscription auto updates when I add new records manually or trigger the api that inserts mongo records:
export class PodcastSearchComponent implements OnInit {
episodeSubscription: Subscription;
episodes$: Observable<Episode[]>;
constructor(
) {}
ngOnInit() {
this.episodeSubscription = MeteorObservable.subscribe( 'episodes' ).subscribe();
this.episodes$ = Episodes.find();
);
This option looks a bit weird, since you setup a subscription, but we don't use a subject (rxjs) and then we just seem to bind Episodes.find(), which is a rxjs mongo observable collection at this time, to the episodes$
observable.
The second method: This subscription DOESN'T auto update, only loads one time on page load:
export class PodcastSearchComponent implements OnInit {
episodes$: Observable<Episode[]>;
constructor(
) {}
ngOnInit() {
this.episodes$ = MeteorObservable.subscribe( 'episodes' ).pipe( switchMap( () => Episodes.find() ) );
I ran into the second method in one of the examples and it looked elegant, but it has some different behaviour than the first method. I would have expected this to work since the RxJS Mongo observable collection that was setup. However it doesn't autorun, or detect changes in my situation.
Should I also use the second method for setting up a subscription?
I hope my questions aren't annoying, I am re-exploring Meteor after 2 years of absence (just pure angular 4 during that time) and I really want it to work with Angular 6.
***Update: at one point I thought it had something to do with ChangeDetectionStrategy.OnPush
but it didn't matter turning that off.
Try to use this way; Subscription is triggered once it's ready, and the collection observable is independently triggered by Meteor's tracker. Please let me know if it is fixed or still occured
ngOnInit(){
this.episodesSubscription = MeteorObservable.subscribe('episodes').subscribe(() => {
this.episodes$ = Episodes.find();
})
}
ngOnDestroy(){
if(this.episodesSubscription){
this.episodesSubscription.unsubscribe();
}
}
I moved my subscription to a service, since I want a singleton watching the episode change and then call the redux action, which is using an @Effect that calls the getAll
function returning the episodes.
When I use the Autorun, I can manually add and remove items to mongo and the list will update.
When I use your slightly altered suggestion (not assigning it episodes$
) it doesn't autorun. It could be because I am not assigning it the observable episodes$
.
@Injectable()
export class EpisodesService {
episodeSubscription: Subscription;
constructor(
private store: Store<fromStore.PodcastsState>,
) {
// this.episodeSubscription = MeteorObservable.subscribe('episodes').subscribe(() => {
// Episodes.find().fetch();
// this.store.dispatch( new fromStore.LoadEpisodes() );
// })
this.episodeSubscription = MeteorObservable.subscribe( 'episodes' ).subscribe();
MeteorObservable.autorun().subscribe(() => {
// triger autorun
Episodes.find().fetch();
this.store.dispatch( new fromStore.LoadEpisodes() );
});
}
getAll(): Observable<Episode[]> {
return of( Episodes.find().fetch() );
}
}
Maybe you should try mergeMap
or somehow.
Or you can use Tracker.autorun
and Meteor.subscribe
to get data inside autorun callback and trigger redux without dealing with RxJS.
hmm, it doesn't help that I don't entirely know what I am doing. This seems to be the only one that works
this.episodeSubscription = MeteorObservable.subscribe( 'episodes' ).subscribe();
MeteorObservable.autorun().subscribe(() => {
// triger autorun
Episodes.find().fetch();
this.store.dispatch( new fromStore.LoadEpisodes() );
});
Adding a mergeMap
in a pipe() after the subscription didn't make it reRun.
Only the Episodes.find().fetch()
inside the autorun triggers a rerun and then does a dispatch of my action.
@ardatan can I ask you something off topic: Do you think Angular, Meteor and NGRX is a bit of overkill? I could do the whole state management in Mongo right? Then the client mini-mongo would be the same as an NgRX Store with pubsub etc.
I though NGRX was the way to go, but I hear a lot of people in the react world mention graphql instead of redux. Would it be better for me to look at Apollo?