Angular

Geoapify lets to send multiple API requests within one call by using Batch service. Learn more about the Batch service on the documentation page.

The Batch service based on asynchronous calls. Here is an implementation of asynchronous calls that can be used for Batch requests from an Angular project.

HTTPClient

We use Angular HTTPClient service to make HTTP calls in this code sample. Import HttpClientModule into your module to be able to use the HTTPClient service.

import { NgModule }         from '@angular/core';
import { BrowserModule }    from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';

@NgModule({
  imports: [
    BrowserModule,
    // import HttpClientModule after BrowserModule.
    HttpClientModule,
  ],
  declarations: [
    AppComponent,
  ],
  bootstrap: [ AppComponent ]
})
export class AppModule {}

Inject the HttpClient service to your class:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable()
export class YourClass {
  constructor(private http: HttpClient) { }
}

Create a batch job and monitor results

We need 2 types requests: HTTP Post request to create a job and HTTP Get request to monitor the job execution and getting result

  • As we interested in response status by checking the response, we use getBodyAndStatus() that provides both response status and response body.
  • If when the job is accepted (HTTP 202) we start monitor results with getAsyncCallResult(). To avoid unnecessary calls we set a timeout to 1000ms (60000ms recommended for bigger jobs) and number of maximal attempts.
  • As soon as results are available, the getAsyncCallResult() promise is resolved.

Code sample

sendRequest(data: any) {
  const url = `https://api.geoapify.com/v1/batch?apiKey=YOU_API_KEY`;
  this.httpClient.post(url, data).subscribe((data: any) => {
    this.response = data;
    this.getAsyncResult(`${url}&id=${data.id}`, 1000, 100).then((result) => {
      this.result = result;
    }, err => {
      this.error = err;
    });
  });
}

private getAsyncResult(url, timeout, maxAttempt) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      repeateUntilSuccess(this.httpClient, resolve, reject, 0)
    }, timeout);
  });

  function repeateUntilSuccess(httpClient, resolve, reject, attemptCount) {
    httpClient.get(url, { observe: 'response' }).subscribe((response: any) => {
      if (response.status === 200) {
        // result is ready
        resolve(response.body);
      } else if (attemptCount >= maxAttempt) {
        reject("Max amount of attempt achived");
      } else if (response.status === 202) {
        // Repeat after timeout
        setTimeout(() => {
          repeateUntilSuccess(httpClient, resolve, reject, attemptCount + 1)
        }, timeout);
      } else {
        // something went wrong
        reject(response.body)
      }
    }, err => {
      reject(err.error)
    })
  }
}