Manual Reference Source

Migration Guide: Moving from v2 to v3

The gsf-javascript-client-sdk has undergone a number of changes for version 3.0. This version is significant due to the adoption of a new HTTP API for GSF. This means that if you upgrade your SDK to v3, you will also need to update your server(s) to GSF version 3.0. Ensure that the gsf-request-handler is enabled on the server before using version 3 of the SDK. There are a number of breaking changes for the SDK user as a result of switching to the new API.

The purpose of this guide is to help you transition your application's source code from v2 to v3 of the SDK.

Server Class

GSF.Server is now GSF.Client.

  • The server class has been renamed to 'Client'.
  • The 'ServerArgs' object is now referred to as 'ClientOptions'.

Client.APIRoot no longer defaults to 'ese'.

  • The default APIRoot has been removed to align with the new HTTP API.

Service Class

Service.info() no longer contains task list.

Service.taskInfoList() response changed.

Task Class

Task.info() response changed.

Task.submit() and Task.submitAndWait() options changed.

Job Class

Job.info() response changed.

  • See JobInfo below for more details.

Job event names changed. They are now the same as the Client events.

- Renamed 'Accepted' to 'JobAccepted'.
- Renamed 'Started' to 'JobStarted'.
- Renamed 'Progress' to 'JobProgress'.
- Renamed 'Completed' to 'JobCompleted'.
- Renamed 'Succeeded' to 'JobSucceeded'.
- Renamed 'Failed' to 'JobFailed'.

Job.wait() response changed.

Types

TaskInfo

  • Added 'serviceName'.
  • Renamed 'name' to 'taskName'.
  • Renamed '<parameter>.dataType' to '<parameter>.type'.
  • Renamed '<parameter>.defaultValue' to '<parameter>.default'.
  • Replaced 'parameters' with 'inputParameters' and 'outputParameters'.
  • Removed '<parameter>.direction'
    • New 'inputParameters' and 'outputParameters' arrays indicate direction in their name.
Example of TaskInfo in v2
{
    "name": "ISODATAClassification",
    "displayName": "ISODATA Classification",
    "description": "This task clusters pixels in a dataset based on statistics only, without requiring you to define training classes.",
    "parameters": {
        "INPUT_RASTER": {
            "name": "INPUT_RASTER",
            "parameterType": "required",
            "displayName": "Input Raster",
            "description": "Specify a raster on which to perform unsupervised classification.",
            "direction": "INPUT",
            "dataType:": "ENVIRASTER"
        },
        "OUTPUT_RASTER": {
            "name": "OUTPUT_RASTER",
            "parameterType": "required",
            "displayName": "Output Raster",
            "description": "This is a reference to the output classification raster of filetype ENVI.",
            "direction": "OUTPUT",
            "dataType:": "ENVIRASTER"
        }
    }
}
Example of TaskInfo in v3
{
    "taskName": "ISODATAClassification",
    "serviceName": "ENVI",
    "displayName": "ISODATA Classification",
    "description": "This task clusters pixels in a dataset based on statistics only, without requiring you to define training classes.",
    "inputParameters": [
        {
            "name": "INPUT_RASTER",
            "type": "ENVIRASTER",
            "required": true,
            "displayName": "Input Raster",
            "description": "Specify a raster on which to perform unsupervised classification."
        }
    ],
    "outputParameters": [
        {
            "name": "OUTPUT_RASTER",
            "type": "ENVIRASTER",
            "displayName": "Output Raster",
            "description": "This is a reference to the output classification raster of filetype ENVI.",
            "required": true
        }
    ]
}

For full documention see TaskInfo.

ServiceInfo

  • Removed 'tasks'.
    • Use Service.tasks() or Service.taskInfoList() to obtain task lists.
Example of ServiceInfo in v2
{
    "name": "ENVI",
    "description": "ENVI processing routines",
    "tasks": [
        "Task1",
        "Task2",
        "Task3"
    ]
}
Example of ServiceInfo in v3
{
    "name": "ENVI",
    "description": "ENVI processing routines"
}

For full documentation see ServiceInfo.

SubmitOptions

  • Added 'jobOptions' object.
    • 'route' was moved into the 'jobOptions' object.
    • Any additional processing directives will reside in the 'jobOptions' object.
  • Renamed 'parameters' to 'inputParameters'.
Example of SubmitOptions in v2
const submitOptions = {
  parameters: {
    INPUT_RASTER: {
      FACTORY: 'URLRaster',
      URL: '/some/url'
    },
    INDEX: 'Normalized Difference Vegetation Index'
  },
  route: "ENVIRoute"
};
Example of SubmitOptions in v3
const submitOptions = {
  inputParameters: {
    INPUT_RASTER: {
      FACTORY: 'URLRaster',
      URL: '/some/url'
    },
    INDEX: 'Normalized Difference Vegetation Index'
  },
  jobOptions: {
      route: "ENVIRoute"
  }
};

For full documentation see SubmitOptions.

JobInfo

  • Added 'jobStart'.
  • Added 'jobEnd'.
  • Added 'jobSubmitted'.
  • Added 'jobOptions'.
  • Renamed 'inputs' to 'inputParameters'.
  • Renamed 'jobErrorMessage' to 'jobError'.
  • Renamed 'results' to 'jobResults'.
  • Renamed 'jobProgressMessage' to 'jobMessage'.
  • Removed 'jobRoute'. This property is now in the 'jobOptions' object.
  • Removed 'jobStatusUrl'.
Example of JobInfo in v2
{
    "jobId": 3410,
    "jobStatus": "Succeeded",
    "jobStatusURL": "ese/jobs/3410/status",
    "jobProgress": 100,
    "jobProgressMessage": "Completed",
    "jobRoute": "default",
    "taskName": "SpectralIndex",
    "serviceName": "ENVI",
    "jobErrorMessage": "",
    "inputs": {
        "index": "Iron Oxide",
        "input_raster": {
            "url": "/some/url",
            "factory": "URLRaster"
        }
    },
    "results": {
        "OUTPUT_RASTER": {
            "url": "/some/url",
            "factory": "URLRaster",
            "auxiliary_url": [
                "/some/url"
            ]
        }
    },
    "messages": [{
            "type": "esriJobMessageTypeInformative",
            "description": "Submission Time: Mon Jan 29 2018 16:07:52 GMT-0700 (Mountain Standard Time)"
        },
        {
            "type": "esriJobMessageTypeInformative",
            "description": "Start Time: Mon Jan 29 2018 16:07:52 GMT-0700 (Mountain Standard Time)"
        },
        {
            "type": "esriJobMessageTypeInformative",
            "description": "End Time: Mon Jan 29 2018 16:08:01 GMT-0700 (Mountain Standard Time) (Elapsed Time: 8.818 seconds)"
        }
    ]
}
Example of JobInfo in v3
{
    "jobId": 3410,
    "jobProgress": 100,
    "jobMessage": "Completed",
    "jobStatus": "Succeeded",
    "taskName": "SpectralIndex",
    "serviceName": "ENVI",
    "inputParameters": {
        "index": "Iron Oxide",
        "input_raster": {
            "url": "/some/url",
            "factory": "URLRaster"
        }
    },
    "jobResults": {
        "OUTPUT_RASTER": {
            "best": {
                "url": "/some/url",
                "factory": "URLRaster",
                "auxiliary_url": [
                    "/some/url"
                ]
            },
            "ese-job-parameter-mapper": {
                "url": "/some/url",
                "factory": "URLRaster",
                "auxiliary_url": [
                    "/some/url"
                ]
            }
        }
    },
    "jobOptions": {
        "route": "default"
    },
    "jobSubmitted": "2018-01-29T23:07:52.992Z",
    "jobStart": "2018-01-29T23:07:52.995Z",
    "jobEnd": "2018-01-29T23:08:01.813Z"
}

For full documentation see JobInfo.

JobResults

  • Each parameter now contains all of the parameter mappings. The highest ranked mapping is set to the 'best' key.
Example of JobResults in v2
{
    "OUTPUT_RASTER": {
        "url": "/some/url",
        "factory": "URLRaster",
        "auxiliary_url": [
            "/some/url"
        ]
    }
}
Example of JobResults in v3
{
    "OUTPUT_RASTER": {
        "best": {
            "url": "/some/url",
            "factory": "URLRaster",
            "auxiliary_url": [
                "/some/url"
            ]
        },
        "ese-job-parameter-mapper": {
            "url": "/some/url",
            "factory": "URLRaster",
            "auxiliary_url": [
                "/some/url"
            ]
        }
    }
}

For full documentation see JobResults.

Migration Guide: Moving from v3 to v4

The purpose of this guide is to help you transition your application's source code from v3 to v4 of the SDK. These changes will allow you to use the SDK with GSF 3.0 or later.

Job IDs

Job IDs are now strings due to the addition of optional unique job IDs in GSF 3.0.

Job Lists

New 'query' option

GSF 3.0 has added a powerful API for querying the job database. The SDK now leverages this new query language and has removed some of the legacy job filters. More information on this can be found in the Examples page or the GSF Job Search API Tutorial.

New 'sort' option

More flexible sorting is now available for job lists. Please see JobListOptions documentation for more details

New 'totals' option

A new option called 'totals' has been introduced to the JobListOptions object. This can be used to retrieve total job counts by job status, as well as a grand total. Please see the JobListOptions documentation for more details.

JobInfoList response has changed

Instead of just returning the array of JobInfo objects, the Client.JobInfoList() function now returns an object containing the count of filtered jobs, the total number of jobs in the database, and totals for each job status. For more information see the [JobInfoList] documentation.

JobInfoList V3

[
    <JobInfo>,
    <JobInfo>,
    ...
]

JobInfoList V4

{
    total: 50,
    count: 10,
    jobs: [
        <JobInfo>,
        <JobInfo>,
        ...
    ]
}

The 'reverse' and 'status' options have been removed

The 'reverse' and 'status' options have been removed from the JobListOptions object in favor of the new query API. Below are examples for converting to the new syntax.

Converting code that uses the 'reverse' option

Setting the 'reverse' option to true is equivalent to sorting the job list by jobSubmitted date in descending order.

const client = GSF.client({
    address: 'MyServer',
    port: '9191'
});

// Get job list with jobSubmitted date in descending order.
const jobListOptions = {
-    reverse: true
+    sort: [[ 'jobSubmitted', -1 ]]
};

client
    .jobs(jobListOptions)
    .then((jobList) => {
        console.log(jobList);
    }).catch((err) => {
        console.error(err);
    });
Converting code that uses the 'status' option

Setting the 'status' option is equivalent to querying by jobStatus using the new syntax. For more examples on querying, please see the Examples or the GSF Job Search API Tutorial.

const client = GSF.client({
    address: 'MyServer',
    port: '9191'
});

// Filter job list by Failed status.
const jobListOptions = {
-    status: 'Failed'
+    query: {
+       jobStatus: {
+           '$eq': 'Failed'
+       }
+    }
};

client
    .jobs(jobListOptions)
    .then((jobList) => {
        console.log(jobList);
    }).catch((err) => {
        console.error(err);
    });

GSF JavaScript Client SDK

About the SDK

The GSF JavaScript Client SDK provides a client-side JavaScript library for interacting with GSF. The SDK works in both the browser and Node.js.

  1. This repository contains pre-built distributable files located in the /dist/ directory.
    • /dist/GSF-node.js - The Node.js bundle.
    • /dist/GSF-node.js.map - The Node.js bundle source map.
    • /dist/GSF.js - The non-minified web bundle.
    • /dist/GSF.js.map - The non-minified web bundle source map file.
    • /dist/GSF.min.js - The minified web bundle.
    • /dist/GSF.min.js.map - The minified web bundle source map file.

Basic Usage

Importing the SDK

Using ECMAScript 2015

  • Import everything with GSF namespace:

    import * as GSF from 'gsf-js-client-sdk';

  • Import specific classes:

    import { Job, Task } from 'gsf-js-client-sdk';

Using Node.js

  • Require the SDK:

    const GSF = require('gsf-js-client-sdk/dist/GSF-node');

Including the SDK with a Script Tag

  1. Include the GSF JavaScript Client SDK in your project. The example below assumes the SDK file is located next to your html file.

    <script src="GSF.min.js"></script>

  2. Access the SDK using the global GSF object.

    <script>console.log(GSF);</script>

  3. Below is a simple example of running a job and retrieving the results. You will need to update the server address and port below to reflect the server that you are using.

const myAddress = 'MyServer';
const myPort = 9191;

// GSF Client
const client = GSF.client({
    address: myAddress,
    port: myPort
  });

// Create a service object.
const service = client.service('ENVI');

// Create a task object.
const task = service.task('SpectralIndex');

const NDVIParameters = {
  inputParameters: {
    INPUT_RASTER: {
      FACTORY: 'URLRaster',
      URL: `http://${myAddress}:${myPort}/ese/data/qb_boulder_msi`
    },
    INDEX: 'Normalized Difference Vegetation Index'
  }
};

// Submit a job.
task.submitAndWait(NDVIParameters).then((results) => {
    // Do something with results.
    AddToMap(results.OUTPUT_RASTER.best);
  }).catch((err) => {
    // Display error.
  });

Requirements

Server Sent Events

The GSF JavaScript Client SDK relies on server-sent events for communication with the server. Developers who wish to build apps that run on browsers lacking EventSource support will want to use a polyfill. This is not necessary when using the SDK in Node.js.

To view a list of the browsers that support EventSource please go here: https://caniuse.com/#search=eventsource

There are several polyfills available that provide implementations of the EventSource API. One such polyfill that is available from the npm and Bower package managers is called 'eventsource-polyfill'. For information on installation and usage, see https://github.com/amvtek/EventSource.

Building the SDK

  1. Clone the repository.

    $ git clone https://github.com/geospatial-services-framework/gsf-js-client-sdk

  2. From the root directory of the project install the dependencies.

    $ npm install

  3. Run the build script.

    $ npm run build

Testing the SDK

Using a Test Server

We have provided a simple mock server implementation that can be used for very basic testing of the SDK. There are several other test scripts available. See the scripts section of the package.json file for more information.

Run tests in the browser against mock server.

$ npm run test

Run tests in Node.js against mock server.

$ npm run test-node

Building the Documentation

  1. Build the documentation.

    $ npm run help

  2. View the generated help files located in the /help directory (on Windows).

    $ start help/index.html

Examples

Below are several examples of using the SDK with JavaScript. For TypeScript specific examples see the TypeScript example. Before using the SDK, it is also recommended that you read the best practices section.

List Available Services

The GSF Client object provides the ability to list the available services on the server.

// GSF Client
const client = GSF.client({
    address: 'MyServer',
    port: '9191'
  });

// Get an array of available services.
client.services().then((services) => {
  services.forEach((service) => {
    // Print each service name.
    console.log(service.name);
  });
}).catch((err) => {
  // There was an error.
});

List Jobs

The GSF Client object provides the ability to query and sort the job list.

The 'query' option

The JobListOptions object supports an option called 'query'. This can be used to form advanced queries of the job database. The primary building block of a query is the comparison operator, which may be used to select jobs matching the desired criteria. The job search API supports the following comparison operators:

  • $eq
  • $gt
  • $gte
  • $lt
  • $lte
  • $ne

A simple query for any job that is not 'Succeeded':

// GSF Client
const client = GSF.client({
    address: 'MyServer',
    port: '9191'
  });

const jobListOptions = {
  query: {
      jobStatus: {
          '$ne': 'Succeeded'
      }
  },
};

// List jobs.
client.jobInfoList(jobListOptions).then((jobInfoList) => {
  // Print job list.
  console.log(jobInfoList);
}).catch((err) => {
  // There was an error.
});

The 'sort' option

In addition to providing a query object, the JobListOptions also allows flexible sorting of the job list. This field should be an array of sort arrays. Multiple sort arrays may also be provided as the sorting will be evaluated from left to right. Each field may be sorted in either ascending (1) or descending (-1) order.

Sort jobs by 'jobSubmitted' date in ascending order.

// GSF Client
const client = GSF.client({
    address: 'MyServer',
    port: '9191'
  });

const jobListOptions = {
  sort: [ [ 'jobSubmitted', 1 ] ]
};

// List jobs.
client.jobInfoList(jobListOptions).then((jobInfoList) => {
  // Print job list.
  console.log(jobInfoList);
}).catch((err) => {
  // There was an error.
});

Advanced query

This example shows all of the features of the job search API used together. The job search below would return the 10 most recent failed Spectral Index jobs in the database. For more information please see the JobListOptions object and the GSF Job Search API Tutorial.

// GSF Client
const client = GSF.client({
    address: 'MyServer',
    port: '9191'
  });

const jobListOptions = {
  query: {
      taskName: {
          '$eq': 'SpectralIndex'
      },
      jobStatus: {
          '$eq': 'Failed'
      }
  },
  sort: [ [ 'jobSubmitted', -1 ] ],
  offset: 0,
  limit: 10,
  totals: 'all'
};

// List jobs.  This will result in an array of Job objects.
client.jobs(jobListOptions).then((jobList) => {
  // Print job list.
  console.log(jobList);
}).catch((err) => {
  // There was an error.
});

// List jobs.  This will result in a list of JobInfo object along with a count and totals.
client.jobInfoList(jobListOptions).then((jobInfoList) => {
  // Print job list.
  console.log(jobInfoList);
}).catch((err) => {
  // There was an error.
});

List Available Tasks

The Service object provides the ability to list the available tasks on the service. The example below lists all tasks associated with the ENVI service.

// GSF Client
const client = GSF.client({
    address: 'MyServer',
    port: '9191'
  });

// Get the ENVI service.
const service = client.service('ENVI');

// Get an array of available tasks.
service.tasks().then((tasks) => {
  tasks.forEach((task) => {
    // Print each task name.
    console.log(task.name);
  });
}).catch((err) => {
  // There was an error.
});

Get Task Information

The Task object allows you to query the task and its parameters. This may be useful when dynamically constructing UI elements representing task input parameters.

// GSF Client
const client = GSF.client({
    address: 'MyServer',
    port: '9191'
  });

// Get the ENVI service.
const service = client.service('ENVI');

// Get a task.
const task = service.task('SpectralIndex');

task.info().then((info) => {
  // Print the task info.
  console.log(info);
}).catch((err) => {
  // There was an error.
});

Run a Task

There are many ways to run tasks and retrieve results using the GSF JavaScript SDK. The following examples assume you have completed the steps below to create a task object.

// Get a task.
const task = GSF.client({address:'MyServer',port:'9191'}).service('ENVI').task('SpectralIndex');

const taskParameters = {
  inputParameters: {
    INPUT_RASTER: {
      FACTORY: 'URLRaster',
      URL: 'http://MyServer:9191/ese/data/qb_boulder_msi'
    },
    INDEX: 'Normalized Difference Vegetation Index'
  }
};

Using Promises

The SDK provides a Promise-based interface for submitting tasks. If the task succeeds, the promise will be fulfilled. If the job fails, the promise will be rejected. There are two ways to use promises for job submission.

1. Use .submit() and then .wait()

The Task.submit() function returns a Promise to a Job, and the Job.wait() function returns a Promise to the JobResults.

// Submit a job.
task.submit(taskParameters)
  .then(job => job.wait())
  .then((results) => {
    // Do something with results.
    // This function is an example and is not provided by the SDK.
    AddToMap(results.OUTPUT_RASTER.best);
  }).catch((jobErrorMessage) => {
    // Display error.
  });
2. Use .submitAndWait()

This function simply combines the .submit() and .wait() functions. This is perhaps the simplest way to submit a job and retrieve the results. Use this if you are only intereseted in results and do not wish to interact with the Job object.

// Submit a job.
task.submitAndWait(taskParameters).then((results) => {
    // Do something with results.
    // This function is an example and is not provided by the SDK.
    AddToMap(results.OUTPUT_RASTER.best);
  }).catch((jobErrorMessage) => {
    // Display error.
  });

List and Retrieve Workspace Files

The GSF Job object provides the ability to fetch a list of workspace files. It is required that the 'enableNodeInfo' configuration is set to true on the server for job workspace access.

The task below, CustomTask, is a fictional task that writes a text file to the job workspace. This also provides an example of using async/await instead of promises.

const task = GSF.client({address:'MyServer',port:'9191'}).service('ENVI').task('CustomTask');

// Submit job.
const job = await task.submit({});

// Wait for job to complete.
await job.wait();

// Get the list of workspace files.
const workspaceFiles = await job.workspace();
console.log(workspaceFiles);
// prints:
// [
//   {
//     dev: 66311,
//     mode: 33204,
//     nlink: 1,
//     uid: 1000,
//     gid: 1000,
//     rdev: 0,
//     blksize: 4096,
//     ino: 11768910,
//     size: 18,
//     blocks: 8,
//     atimeMs: 1604352379848.0715,
//     mtimeMs: 1604352379848.0715,
//     ctimeMs: 1604352379848.0715,
//     birthtimeMs: 1604352379848.0715,
//     atime: "2020-11-02T21:26:19.848Z",
//     mtime: "2020-11-02T21:26:19.848Z",
//     ctime: "2020-11-02T21:26:19.848Z",
//     birthtime: "2020-11-02T21:26:19.848Z",
//     path: "file.txt"
//   }
// ]

// Retrieve the contents of a text file.
const fileBuffer = await job.file(workspaceFiles[0].path);
const textDecoder = new TextDecoder('utf-8');
const fileContents = textDecoder.decode(fileBuffer);
console.log(fileContents); // prints: Text file contents.

Using Server Events

The Client and Job objects give you access to all job related events emitted by the server. These classes inheret from Node's EventEmitter and support methods such as .on(), .once(), .removeAllListeners(), etc. The following example shows how to listen for job events on the Client.

// GSF Client
const client = GSF.client({
    address: 'MyServer',
    port: '9191'
  });

// Set up an event listeners.
client.once('JobSucceeded', (data) => {
  console.log('Job Succeeded: ', data.jobId);
});

client.once('JobFailed', (data) => {
  console.log('Job Failed: ', data.jobId);
});

// Create a service object.
const service = client.service('ENVI');

// Create a task object.
const task = service.task('SpectralIndex');

const NDVIParameters = {
  inputParameters: {
    INPUT_RASTER: {
      FACTORY: 'URLRaster',
      URL: 'http://MyServer:9191/ese/data/qb_boulder_msi'
    },
    INDEX: 'Normalized Difference Vegetation Index'
  }
};

// Submit a job.
task.submit(NDVIParameters);

For a complete list of available events, see the Client class documentation.

Tracking Job Progress

There are two ways to track the progress of a job.

Progress Callbacks

The .submit() and .submitAndWait() functions support the inclusion of a progress callback for reporting job progress.

const progressCallback = function (data) {
  console.log('Job progress percent: ', data.progress);
  console.log('Job progress message: ', data.message);
};

// Submit a job.
task.submitAndWait(parameters, progressCallback).then((results) => {
    // Do something with results.
    // This function is an example and is not provided by the SDK.
    AddToMap(results.OUTPUT_RASTER.best);
  }).catch((jobErrorMessage) => {
    // Display error.
  });

Progress Events

Job progress events are emitted by the Client and Job objects.

Client Progress Events

It is possible to listen to all job progress events emitted by the server using the Client object.

// GSF Client
const client = GSF.client({
    address: 'MyServer',
    port: '9191'
  });

// Set up an event listeners.
client.on('JobProgress', (data) => {
  console.log('Job: ', data.jobId, ' progress percent: ', data.progress);
  console.log('Job: ', data.jobId, ' progress message: ', data.message);
});

// Create a service object.
const service = client.service('ENVI');

// Create a task object.
const task = service.task('SpectralIndex');

const NDVIParameters = {
  inputParameters: {
    INPUT_RASTER: {
      FACTORY: 'URLRaster',
      URL: 'http://MyServer:9191/ese/data/qb_boulder_msi'
    },
    INDEX: 'Normalized Difference Vegetation Index'
  }
};

// Submit a job.
task.submit(NDVIParameters);

Job Progress Events

A Job object emits progress events for the particular job which it represents.

// GSF Client
const client = GSF.client({
    address: 'MyServer',
    port: '9191'
  });

// Create a service object.
const service = client.service('ENVI');

// Create a task object.
const task = service.task('SpectralIndex');

const NDVIParameters = {
  inputParameters: {
    INPUT_RASTER: {
      FACTORY: 'URLRaster',
      URL: 'http://MyServer:9191/ese/data/qb_boulder_msi'
    },
    INDEX: 'Normalized Difference Vegetation Index'
  }
};

// Submit a job.
task.submit(NDVIParameters).then((job) => {
  // Set up an event listener on the job.
  job.on('JobProgress', (data) => {
    console.log('Job ', data.jobId, ' progress percent: ', data.progress);
    console.log('Job ', data.jobId, ' progress message: ', data.message);
  });
}).catch((jobErrorMessage) => {
  // Display error.
});

Cancelling Jobs

Below is an example of cancelling a job based on its job ID.

const myJobId = 1;
const job = new client.job(myJobId);
const force = false; // Do not force cancel.

// Cancel Job
job.cancel(force).then(() => {
  console.log('Cancel has been successfully requested.');
}).catch((err) => {
  // Display error.
});

Typescript Example

Below is an example of submitting a job using typescript.

import * as GSF from 'gsf-js-client-sdk';

// Get a task.
const clientOptions: GSF.ClientOptions = {address: 'MyServer', port: '9191'};
const myClient: GSF.Client = GSF.client(clientOptions);
const ENVIService: GSF.Service = myClient.service('ENVI');
const myTask: GSF.Task = ENVIService.task('SpectralIndex');

const taskParameters: GSF.SubmitOptions = {
    inputParameters: {
        INPUT_RASTER: {
            FACTORY: 'URLRaster',
            URL: 'http://MyServer:9191/ese/data/qb_boulder_msi'
        },
        INDEX: 'Normalized Difference Vegetation Index'
    }
};

// Submit a job.
task.submitAndWait(taskParameters)
    .then((results: GSF.JobResults) => {
        // Do something with results.
        // This function is an example and is not provided by the SDK.
        AddToMap(results.OUTPUT_RASTER.best);
    }).catch((jobErrorMessage) => {
        // Display error.
    });

Best Practices

Connecting to Servers

The examples throughout this documentation explain various concepts within the SDK using complete examples. Most of the examples create a new Client object for every example. This is to ensure a fully functional and self-contained example but is not a good practice when developing web apps. It is recommended that you limit the number of Client objects that you create. Ideally, your app will create only one instance of this class and pass the reference around where needed. This helps ensure consistency and prevent the possibility of exceeding the browser's per-domain connection limit.

Change Log

All notable changes to this project will be documented in this file.

4.2.0 / 2021-10-26

New Features

  • Support for GSF 3.0:
    • Add job delete functionality, matching job deletion functionality in GSF.

4.0.0 / 2020-06-22

New Features

  • Support for GSF 3.0:
    • Add 'query' option to JobListOptions for more advanced querying of the job database.
    • Add 'sort' option to the JobListOptions for flexible sorting of the job list.
    • Add 'totals' option to JobListOptions for totals broken down by job status.

Breaking Changes

  • Changes related to GSF 3.0:
    • Change jobId type from number to string to support the new 'uniqueJobIds' configuration option in GSF.
    • Remove 'reverse' and 'status' options from JobListOptions in favor or more powerful 'sort' and 'query' options.
    • The JobInfoList is now an object containing the jobs array, job count, and totals.

For a detailed summary of the changes, see the V4 Migration Guide and examples in the documentation.

3.0.0 / 2018-03-21

New Features

  • Updated the SDK to use the new GSF HTTP API.

Breaking Changes

  • Several breaking changes were made for this release. For a detailed summary of the changes, see the Migration Guide in the documentation.

2.2.0 / 2018-03-22

New Features

  • Added Server.jobInfoList() for fetching an array of the current JobInfo objects.

Bug Fixes

  • Fix #10 - Server.jobInfoList() will retrieve full JobInfo objects from the server.

2.1.0 / 2018-03-21

New Features

  • Added headers object to the ServerArgs object to allow custom headers to be used in requests.

2.0.0 / 2017-07-24

New Features

  • Added the ability to use the SDK in Node.js. See documentation for more details.

Breaking Changes

  • Task class: Replaced 'server' and 'serviceName' constructor arguments with 'service'. This only affects Task objects created using the Task class constructor; there is no change to Task objects created using the Service.Task() method. See API documentation for more details.

1.0.0 / 2017-02-26

New Features

  • Add a change log.