File

src/paginationCalls/pagedApiCaller.ts

Implements

APICaller

Index

Properties
Methods

Constructor

constructor(pageDescriptor: PageDescriptor)

Creates an API caller that returns a stream to performs page-streaming.

Parameters :
Name Type Optional Description
pageDescriptor PageDescriptor No
  • indicates the structure of page streaming to be performed.

Properties

pageDescriptor
Type : PageDescriptor

Methods

call
call(apiCall: SimpleCallbackFunction, argument: literal type, settings: CallOptions, canceller: OngoingCall)
Parameters :
Name Type Optional
apiCall SimpleCallbackFunction No
argument literal type No
settings CallOptions No
canceller OngoingCall No
Returns : void
fail
fail(canceller: OngoingCallPromise, err: GoogleError)
Parameters :
Name Type Optional
canceller OngoingCallPromise No
err GoogleError No
Returns : void
init
init(settings: ApiCallerSettings, callback?: APICallback)
Parameters :
Name Type Optional
settings ApiCallerSettings No
callback APICallback Yes
Returns : any
result
result(canceller: OngoingCallPromise)
Parameters :
Name Type Optional
canceller OngoingCallPromise No
Returns : any
wrap
wrap(func: GRPCCall)
Parameters :
Name Type Optional
func GRPCCall No
Returns : GRPCCall
import {APICaller, ApiCallerSettings} from '../apiCaller';
import {
  GaxCall,
  GRPCCall,
  NextPageRequestType,
  SimpleCallbackFunction,
  UnaryCall,
} from '../apitypes';
import {APICallback} from '../apitypes';
import {OngoingCall, OngoingCallPromise} from '../call';
import {CallOptions} from '../gax';
import {GoogleError} from '../googleError';

import {PageDescriptor} from './pageDescriptor';

export class PagedApiCaller implements APICaller {
  pageDescriptor: PageDescriptor;
  /**
   * Creates an API caller that returns a stream to performs page-streaming.
   *
   * @private
   * @constructor
   * @param {PageDescriptor} pageDescriptor - indicates the structure
   *   of page streaming to be performed.
   */
  constructor(pageDescriptor: PageDescriptor) {
    this.pageDescriptor = pageDescriptor;
  }

  private createActualCallback(
    request: NextPageRequestType,
    callback: APICallback
  ): APICallback {
    const self = this;
    return function fetchNextPageToken(
      err: Error | null,
      response: NextPageRequestType | undefined
    ) {
      if (err) {
        callback(err);
        return;
      }
      if (!response) {
        callback(
          new GoogleError('Undefined response in pagination method callback.')
        );
        return;
      }
      const resources = response[self.pageDescriptor.resourceField];
      const pageToken = response[self.pageDescriptor.responsePageTokenField];
      if (pageToken) {
        request![self.pageDescriptor.requestPageTokenField] = pageToken;
        callback(err, resources, request, response);
      } else {
        callback(err, resources, null, response);
      }
    };
  }

  wrap(func: GRPCCall): GRPCCall {
    const self = this;
    return function wrappedCall(argument, metadata, options, callback) {
      return (func as UnaryCall)(
        argument,
        metadata,
        options,
        self.createActualCallback(argument, callback)
      );
    };
  }

  init(settings: ApiCallerSettings, callback?: APICallback) {
    if (callback) {
      return new OngoingCall(callback);
    }
    return new OngoingCallPromise(settings.promise);
  }

  call(
    apiCall: SimpleCallbackFunction,
    argument: {[index: string]: {}},
    settings: CallOptions,
    canceller: OngoingCall
  ) {
    argument = Object.assign({}, argument);
    if (settings.pageToken) {
      argument[this.pageDescriptor.requestPageTokenField] = settings.pageToken;
    }
    if (settings.pageSize) {
      argument[this.pageDescriptor.requestPageSizeField!] = settings.pageSize;
    }
    if (!settings.autoPaginate) {
      // they don't want auto-pagination this time - okay, just call once
      canceller.call(apiCall, argument);
      return;
    }

    const maxResults = settings.maxResults || -1;
    const allResources: Array<{}> = [];
    function pushResources(err, resources, next) {
      if (err) {
        canceller.callback!(err);
        return;
      }

      for (let i = 0; i < resources.length; ++i) {
        allResources.push(resources[i]);
        if (allResources.length === maxResults) {
          next = null;
          break;
        }
      }
      if (!next) {
        canceller.callback!(null, allResources);
        return;
      }
      setImmediate(apiCall, next, pushResources);
    }

    setImmediate(apiCall, argument, pushResources);
  }

  fail(canceller: OngoingCallPromise, err: GoogleError): void {
    canceller.callback!(err);
  }

  result(canceller: OngoingCallPromise) {
    return canceller.promise;
  }
}

result-matching ""

    No results matching ""