How to make one Observable sequence wait for another to complete before emitting?
A couple ways I can think of
import {take, publish} from 'rxjs/operators'
import {concat} from 'rxjs'
//Method one
var one = someObservable.pipe(take(1));
var two = someOtherObservable.pipe(take(1));
concat(one, two).subscribe(function() {/*do something */});
//Method two, if they need to be separate for some reason
var one = someObservable.pipe(take(1));
var two = someOtherObservable.pipe(take(1), publish());
two.subscribe(function(){/*do something */});
one.subscribe(function(){/*do something */}, null, two.connect.bind(two));
wait Until a second Observable emits
You want to run a second observable when a first observable emits a non-null value. To do this, use concatMap
or switchMap
after skipWhile
.
ngOnInit() {
const init$ = new BehaviorSubject(null);
const source = new BehaviorSubject({profile:"me"});
const pipedSource = init$
.pipe(
skipWhile((res)=> res === null),
concatMap(() => source)
);
pipedSource.subscribe(val => console.log('first', val));
//init emits once
setTimeout(()=>{
init$.next(1);
},2000);
// a second subscription to source
setTimeout(()=>{
pipedSource.subscribe(val => console.log('second', val));
}, 3000);
}
Here I am subscribing to the init$
observable first, waiting for it to emit a non-null value, and then switching to the source
observable.
DEMO: https://stackblitz.com/edit/angular-p7kftd
Wait for observable to give value to variable before trying to do something with it
Assuming someObservable$
is an observable for a HTTP request, move the code that relies on this.ref
to be inside the subscription handler. Here's an example:
someObservable$.subscribe(response => {
this.ref = response;
// Do whatever work relies on this.ref here.
});
The subscription handler is fired once you receive a response from the HTTP request. So that should be the time to do the work needed. If this.ref
is a variable for a template, then the template should take care of updating the view with the new value automatically.
Making one observable after the other one is complete
You shouldn't subscribe to the first observable, but instead use one more operator to finally subscribe to the second observable.
The operator you want is either mergemap or switchmap.
Could you try this ?
this.router.events
.filter(event => event instanceof NavigationEnd)
.startWith({})
.pairwise()
.tap((events: [NavigationEnd, NavigationEnd]) => {
if (
this.breadcrumbs.length > 0 &&
events[0].url &&
events[0].url.split("?")[0] === events[1].url.split("?")[0]
) {
return;
}
let root: ActivatedRoute = this.activatedRoute.root;
this.breadcrumbs = this.getBreadcrumbs(root);
this.checkSetIsHomePage();
this.setBreadcrumbHeight();
})
.switchMap(() => this.breadcrumbService.additionalBreadcrumbs)
.takeUntil(this.destroy$)
.subscribe(breadcrumb => {
if (breadcrumb.index) {
this.breadcrumbs.splice(breadcrumb.index, 0, breadcrumb);
} else {
this.breadcrumbs.push(breadcrumb);
}
this.setBreadcrumbHeight();
});
What you do here is use the tap operator to manipulate your "this" on each emit, but you don't change the observable and you don't emit one yourself. Then you switch to the second observable, on each emit of the first.
Angular Observable wait for method to execute before return
Use switchMap
like this
this.postService.addPost(post).pipe(
switchMap((newPost: Post) => {
if(selectedFilePaths.length !== 0) {
return this.imageService.uploadPostImages(newPost, selectedFilePaths).pipe(
map(() => newPost),
);
}
return of(newPost);
})
)
Related Topics
How to Detect Browser Refresh Using Angular
Regular Expression for Not Allowing Spaces in the Input Field
Clear an Input Field With Reactjs
Hide Menu Sidebar When Clicking Outside the Bar or the Button
How to Kill a Running Process on Windows from Nodejs
How to Force Clients to Refresh JavaScript Files
How to Pass Id from Modal in Boostrap to PHP File
Remove the Default Browser Header and Footer When Printing HTML
Append Data to Json Array Issue
How to Get the Value by a Key from a Super Nested Json
Regex for Names Validation Allow Only Letters and Spaces
Using JavaScript to Detect Whether the Url Exists Before Display in Iframe
How to Style HTML Select Option Hover and Selected Option Effects
How to Vertically and Horizontally Center a Component in React
How to Create Expand/Collapse Function for Each Row of Table - Angular6
Securityerror: Blocked a Frame With Origin from Accessing a Cross-Origin Frame