Observable in observable with conditions - Angular 10
Obervable in obervable with conditions - Angular 10
我想在表格中添加一本书。
用户手动输入作者姓名。当用户提交表单时,它应该首先检查作者是否存在:
- 如果不是它创建作者
- 如果它已经存在,它只检索作者信息 (id)
- 然后添加作者id
的书
我想我可以让它工作:
formSubmit() {
this.authorService.getByName(this.authorName).subscribe(author => {
// Author exists
if (author.id) {
this.book.author = author;
this.bookService.add(this.book).subscribe(() => {
// Book added
});
} else {
const authorObj: AuthorInterface = {
fullName = this.authorName;
}
this.authorService.add(authorObj); subscribe(author => {
this.book.author = author;
this.bookService.add(this.book).subscribe(() => {
// Book added
});
})
}
});
}
但这真的很糟糕,我相信我可以用 rxjs
使它更干净,但找不到解决方案。我对如何使用所有这些功能有点困惑。
非常感谢您的帮助。非常感谢:)
您可以使用 switchMap。此运算符订阅您传递给它的另一个可观察对象并输出其结果。
this.authorService.getByName(this.authorName)
.pipe(
switchMap(author => {
if (author.id) {
this.book.author = author;
return this.bookService.add(this.book).pipe(...);
}
return this.authorService.add(authorObj).pipe(
switchMap(author => ...)
);
})
)
.subscribe();
如果它是一个大的可观察值(许多发出的值),你最好留在 if else
this.authorService
.getByName(this.authorName)
.pipe(
mergeMap((author: any) => {
if (author.id) {
this.book.author = author;
return this.bookService.add(this.book).pipe(
tap(() => {
console.log("book added");
})
);
} else {
const authorObj: AuthorInterface = {
fullName: this.authorName
};
return this.authorService.add(authorObj).pipe(
mergeMap((author: any) => {
this.book.author = author;
return this.bookService.add(this.book).pipe(
tap(() => {
console.log("book added");
})
);
})
);
}
})
)
.subscribe(() => console.log("job done"));
或者您可以这样做:
const firstObservable = this.authorService.getByName(this.authorName).pipe(
filter((author: any) => author.id != null),
mergeMap(author => {
this.book.author = author;
return this.bookService.add(this.book).pipe(
tap(() => {
console.log("book added");
})
);
})
);
const secondObservable = this.authorService.getByName(this.authorName).pipe(
filter((author: any) => author.id == null),
mergeMap((author: any) => {
const authorObj: AuthorInterface = {
fullName: this.authorName
};
return this.authorService.add(authorObj).pipe(
mergeMap((author: any) => {
this.book.author = author;
return this.bookService.add(this.book).pipe(
tap(() => {
console.log("book added");
})
);
})
);
})
);
merge(firstObservable, secondObservable).subscribe(author =>
console.log("job done")
);
我想在表格中添加一本书。
用户手动输入作者姓名。当用户提交表单时,它应该首先检查作者是否存在:
- 如果不是它创建作者
- 如果它已经存在,它只检索作者信息 (id)
- 然后添加作者id 的书
我想我可以让它工作:
formSubmit() {
this.authorService.getByName(this.authorName).subscribe(author => {
// Author exists
if (author.id) {
this.book.author = author;
this.bookService.add(this.book).subscribe(() => {
// Book added
});
} else {
const authorObj: AuthorInterface = {
fullName = this.authorName;
}
this.authorService.add(authorObj); subscribe(author => {
this.book.author = author;
this.bookService.add(this.book).subscribe(() => {
// Book added
});
})
}
});
}
但这真的很糟糕,我相信我可以用 rxjs
使它更干净,但找不到解决方案。我对如何使用所有这些功能有点困惑。
非常感谢您的帮助。非常感谢:)
您可以使用 switchMap。此运算符订阅您传递给它的另一个可观察对象并输出其结果。
this.authorService.getByName(this.authorName)
.pipe(
switchMap(author => {
if (author.id) {
this.book.author = author;
return this.bookService.add(this.book).pipe(...);
}
return this.authorService.add(authorObj).pipe(
switchMap(author => ...)
);
})
)
.subscribe();
如果它是一个大的可观察值(许多发出的值),你最好留在 if else
this.authorService
.getByName(this.authorName)
.pipe(
mergeMap((author: any) => {
if (author.id) {
this.book.author = author;
return this.bookService.add(this.book).pipe(
tap(() => {
console.log("book added");
})
);
} else {
const authorObj: AuthorInterface = {
fullName: this.authorName
};
return this.authorService.add(authorObj).pipe(
mergeMap((author: any) => {
this.book.author = author;
return this.bookService.add(this.book).pipe(
tap(() => {
console.log("book added");
})
);
})
);
}
})
)
.subscribe(() => console.log("job done"));
或者您可以这样做:
const firstObservable = this.authorService.getByName(this.authorName).pipe(
filter((author: any) => author.id != null),
mergeMap(author => {
this.book.author = author;
return this.bookService.add(this.book).pipe(
tap(() => {
console.log("book added");
})
);
})
);
const secondObservable = this.authorService.getByName(this.authorName).pipe(
filter((author: any) => author.id == null),
mergeMap((author: any) => {
const authorObj: AuthorInterface = {
fullName: this.authorName
};
return this.authorService.add(authorObj).pipe(
mergeMap((author: any) => {
this.book.author = author;
return this.bookService.add(this.book).pipe(
tap(() => {
console.log("book added");
})
);
})
);
})
);
merge(firstObservable, secondObservable).subscribe(author =>
console.log("job done")
);