我正在尝试使用Angular 9开发一个向Google Books API发出请求的应用程序。
但是,requestBookByISBN(isbn: string)
中的.subscribe调用导致页面刷新。我想避免这种情况。
private callAPI(isbn: string): Observable<GoogleBook[]> {
return this.httpClient
.get<{ results: GoogleBook[] }>
(`https://www.googleapis.com/books/v1/volumes?q=${isbn}&key=${ApiLookupService.API_KEY}`)
.pipe(map(matches => matches.results || []));
}
public requestBookByIsbn(isbn: string): GoogleBook[] {
const bookResults: Observable<GoogleBook[]> = this.callAPI(isbn);
let books: GoogleBook[] = [];
bookResults.subscribe(data => books = data);
return books;
}
编辑:这是component.ts文件的一部分,其中包含代码的相关部分:
import {Component, OnInit} from '@angular/core';
import {BookServiceImpl} from '../../shared/Book/service/book.service.impl';
import {CopyServiceImpl} from '../../shared/Copy/service/copy.service.impl';
import {AuthorServiceImpl} from '../../shared/Author/service/author.service.impl';
import {FormControlSettings} from '../FormControlSettings/form.controls.settings';
import {FormBuilder, FormControl, FormGroup} from '@angular/forms';
import {Author} from '../../shared/Author/model/Author';
import {first} from 'rxjs/operators';
import {ToastrService} from 'ngx-toastr';
import {Book} from '../../shared/Book/model/Book';
import {Copy} from '../../shared/Copy/model/Copy';
import {SharedService} from '../../shared/services/shared.service';
import {Subscription} from 'rxjs';
import {ApiLookupService} from '../../shared/services/api.lookup.service';
@Component({
selector: 'app-addbook',
templateUrl: './addbook.component.html',
styleUrls: ['./addbook.component.css']
})
export class AddbookComponent implements OnInit {
// forms
public submitted = false;
public loading = false;
public error = '';
public initAuthorsSubscription: Subscription;
public authors: Author[] = [];
public selectedAuthors: Author[]; // chosen in ng select
constructor(private bookService: BookServiceImpl,
private copyService: CopyServiceImpl,
private authorService: AuthorServiceImpl,
private formBuilder: FormBuilder,
private toastr: ToastrService,
public sharedService: SharedService,
public apiLookupService: ApiLookupService) {
}
public ngOnInit(): void {
this.initAuthors();
this.initBookForm();
this.getInitAuthorsEvent();
}
public findAuthors(ids: number[]): Author[] {
const authors = [];
for (const id of ids) {
this.authorService.findById(id).subscribe(value => authors.push(value));
}
console.log(authors);
return authors;
}
public isbnLookUp() {
console.log(this.apiLookupService.requestBookByIsbn(this.isbnControl.value));
}
public initBookForm(): void {
// assinging form controls
this.bookForm = new FormGroup({
// more assigning going on here
});
}
public initAuthors() {
this.authorService.findAll().subscribe(data => {
this.authors = data.map((author) => {
author.fullName = this.authorService.getFullName(author);
return author;
});
});
}
public getInitAuthorsEvent(): any {
this.initAuthorsSubscription = this.sharedService.initAuthors().subscribe(
() => this.initAuthors());
}
public onSubmit() {
// values are assigned here
this.bookService.add(book)
.pipe(first())
.subscribe(
data => {
this.toastr.success('Buch erfolgreich hinzugefügt!');
copy.reference = data;
for (let i = 0; i < this.amountControl.value; i++) {
this.copyService.add(copy).pipe(first()).subscribe();
}
/*this.sharedService.sendCloseModal();
this.sharedService.sendCloseModal();*/
},
error => {
this.loading = false;
this.toastr.warning(error);
this.error = error;
}
);
}
}
另一个猜测是与其他订阅呼叫存在冲突。
答案 0 :(得分:0)
我不确定这是否是刷新的原因,但是bookResults.subscribe
是异步操作,因此您实际上是返回一个空数组,然后在某个未指定的点将其修改为完整数据。 / p>
您可以通过以下两种方法来解决该特定问题:使用RXjs或promises:
RXjs选项:
public requestBookByIsbn(isbn: string): GoogleBook[] {
return this.callApi(isbn);
}
然后只需让调用requestBookByIsbn
的组件进行订阅并在该点设置数据。
承诺选项:
public async requestBookByIsbn(isbn: string): GoogleBook[] {
const bookResults: Promise<GoogleBook[]> = this.callAPI(isbn).toPromise();
return await bookResult;
}
我猜测刷新发生的位置可能在您向我们展示的部分之外。
如果要重定向到“ / login”以检查用户是否已登录,则在该重定向中,应将当前路径添加为history state或查询参数,然后一次重定向到该路径登录完成而不是重定向到“ /”。