I'm using Angular 7 and building a webapp retrieving data from a REST-API endpoint. Users put their search string into an common formControl
field which is observed. If the value changes in the input field a http request will send to the API endpoint. Finally I get the http response as an observable that I can subscribe. But the query result can also have more than 100 items. Then the API endpoint send a NEXT link to the second page and so on (pagination at API endpoint).
My problem is right now, I don't find the right way to observe the search input field AND interate through all NEXT pages I get from the API endpoint. Separately it works like a charm.
Does anybody have a good practice for my use case?
My component file:
export class GeomapComponent implements OnInit {
searchTerm = new FormControl();
constructor(private geomapService: GeomapService) { }
ngOnInit() {
this.searchTerm.valueChanges.pipe(
debounceTime(400),
distinctUntilChanged(),
switchMap(term => this.geomapService.retrieveApi(term))
).subscribe(data => {
if (data['results']) {
......
}
}
}
}
My service file:
export class GeomapService {
retrieveUrl = new Subject<string>();
constructor(private http: HttpClient) { }
public retrieveApi(searchTerm: string): Observable<ApiDataResponse> {
this.retrieveUrl.next(baseApiUrl + '?q=' + searchTerm);
return this.retrieveUrl.pipe(
switchMap(url => this.sendRequest(url)),
).subscribe(data => {
if (data['next']) {
this.retrieveUrl.next(data['next']);
}
});
}
public sendRequest(url: string, httpOptions = {}): Observable<ApiDataResponse> {
return this.http.get<ApiDataResponse>(url);
}
}
Unfortunately I get the following error:
TS2322: Type 'Subscription' is not assignable to type 'Observable'. Property '_isScalar' is missing in type 'Subscription'.
UPDATE: Right now I am a bit further because I realized that I have to merge / concart sequential incoming observables in the service (provided by a loop).
public requestApi(requestUrl: string): Observable<ApiDataResponse> {
return this.sendRequest(requestUrl).pipe(
mergeMap(result => {
if (result['next']) {
return this.requestApi(result['next']);
} else {
return of(result);
}
})
);
}
Nevertheless I still hanging with the right combination / transformation operator, because in this stage with mergeMap
I get on subscription just the result of the last response. But I also want to get all responses received before and merged as one value.
Does anybody have an idea how should the returns in the operator should look like?
UPDATE:
Code update, removed array issue (ApiDataResponse[]
--> ApiDataResponse
)