Api class
The Api class is a set of wrappers to allow you to retrieve data from an external API.
get
public get(path: string, options?: ApiRequestOptions): Promise<any>
Will by default return all of the data from either the local indexedDB or the server regardless of if there have been any changes. If you want to override this behaviour then set the onlyChanges: boolean
flag of options?:ApiRequestOptions
to `true'
Example
config.api.get("endpoint").then(data => {
// store the data locally in the client
this.dataStore = data;
});
Or to keep the data in the local DB, subsequent calls to this endpoint
will retrieve the local data and then update the local datastore with new values.
config.api.get("endpoint", { datastore: "ds-name", retrieve: { key: value }}).then(data => {
// store the data locally in the client
this.dataStore = data;
});
post
public post(path: string, data: any): Promise<any>
Won't let you automatically write to the local indexedDB - you can of course still do that but you'll have to manage it yourself.
Example
config.api.post("endpoint", {
key1: value,
obj1: { key: value },
array1: [1,2,3,4],
}).then(data => {
// do something on success
}).catch(reject => {
// do some thing on fail
});
subscribe
public subscribe(path: string, options: ApiRequestOptions, success: any, fail: any): string
Will initially supply a full copy of the data (via a call to get()
), and then subsequently will only return data if it differs from the data in the local indexedDB version.
The return type of this function is a string, as it returns a reference to the subscription.
On a successfull call to the remote API the success function is called.
After a number of failed calls to the remote API the subscription is stopped.
Example
The Component base class has wrappers for the api.subscribe methods - this is to allow for easy management of the subscriptions during page navigation.
this.subscribe("endpoint", { datastore: "ds-name", retrieve: { key: value }}, (success: any) => {
// do something with the new data
this.updateUI(success);
}, (reject: any) => {
// do something when the api fails to get data
}).then(ref => {
// do something with the reference to this subscription
});
unsubscribe
public unsubscribe(id: string): void
This will remove a particular success / fail call combination from being fired when a subscription gets new data. If its the last one listening to that subscription, the subscription will be stopped.
Example
As with subscribe
the Component base class has a wrapper for this to make managing it easy.
this.unsubscribe(this.subref);
Or a common use case would be to unsubscribe
from all endpoints when the Component is navigated away from. The Routing component will call the blur()
method of the current component before rendering the next. This is actually coded into the Component base class blur()
method, so using the Componet wrappers will automatically do this:
// keep removing the first on the array until there are none left
while (this.subscriptions.length > 0)
this.unsubscribe(this.subscriptions[0]);
Managing subscriptions
The api has two built in classes to temporarily stop / start subscriptions while maintaing their configurations. Calling these will either pause or start all subscriptions
config.api.pauseSubscriptions();
config.api.resumeSubscriptions();
form
public form(path: string, $form: JQuery): Promise<any>
Form data can also be posted to remote API's via an extention of the post method. This can be used for file uploads.
Example
<form>
<div class="form-group">
<label>File</label>
<div class="input-group">
<div class="custom-file">
<input type="file" name="upload-file" class="custom-file-input" data-bind-change="fileSelected" id="data-import-file">
<label class="custom-file-label" for="data-import-file">Choose file</label>
</div>
<div class="input-group-append">
<button style="width: 100px;" class="btn btn-outline-secondary" disabled="disabled" data-bind-click="processFile" type="button">Upload</button>
</div>
</div>
</div>
</form>
config.api.form("endpoint", $form).then(reply => {
this.fileToken = reply;
});
Class definition
class Api {
// new up an instance of the localDB to store data on the client
private localDb: LocalDB = new LocalDB();
// path to the API
private baseHref: string = "";
// replace this with what ever aut token you are expecting
private token: string = null;
// do you need to call a specific version
private apiVersion: number = 0;
// set your headers, by default it uses a home grown auth token on the X-Authentication header
private headers: any = {
"Content-Type": "application/json",
"X-Authentication": "",
"Accept": "application/json, text/plain, */*;" + (this.apiVersion > 0 ? "version=" + this.apiVersion + ";" : "")
}
// list of all api subscriptions
private subsriptions = []
// pass in the base URL to your API.
constructor(baseHref?: string)
// for authenticating your users
public auth(model: AuthModel): Promise<any>
// to end the session
public logout()
// send a request to your API
private send(request: ApiRequest): Promise<any>
// the send() method expects certain data, this builds that for you
public createRequest(url: string, method: string = null, data: any = null): ApiRequest
// subscribe allows you to repeatedly call an endpoint on your API and process the results via a number of handlers
public subscribe(path: string, handler: any, options: ApiRequestOptions): string
// once subscribed its nice to be able to stop
// if this is the last callback to be removed, the Subscription.stop() method will then be called
public unsubscribe(id: string): void
// this is a helper function to make GET requests easier - uses send() under the covers
public get(path: string, options?: ApiRequestOptions): Promise<any>
// this is a helper function to make POST requests easier - uses send() under the covers
public post(path: string, data: any): Promise<any>
}
AuthModel class
// this is the authentication data, make this match what you need to send through to your auth endpoint
class AuthModel {
EmailAddress: string;
PhoneNumber: number;
Password: string;
}
ApiRequest class
// names match the required names used by $.ajax()
class ApiRequest {
method: string;
url: string;
headers: any;
data: string;
}
ApiRequestOptions class
// a wrapper object to detail where the data is stored in the localDB
class ApiRequestOptions {
datastore: string;
retrieve: any;
onlyChanges: boolean = false; // true = only those that have chnaged from localDB, false = all regardless of changes
}
Subscription class
// Subscriptions allow API endpoints to be called periodically and update registered Components with the data.
class Subscription {
started: boolean = false;
url: string;
callbacks: any[] = [];
interval: number;
private api: Api;
private options: ApiRequestOptions;
// the constructor registered a callback and if not started calls start()
constructor(path: string, api: Api, options: ApiRequestOptions)
// start a subscription - this begins the periodic requests to the Api
// the Api is called every 5 seconds (currently hardcoded)
start(): void
// stop a subscription - this stops the periodic requests.
// The callbacks are still registered so a subsequent call to start() will resume
stop(): void
}