README
@cinchy-co/angular-sdk
Installation
To install this library, go to your angular project directory and use:
$ npm install @cinchy-co/angular-sdk --save
Please use version 2.x.x and 3.x.x if you are using Angular 6 / Angular 7 / Angular 8 and Cinchy v2.x.x / Cinchy v3.x.x.
Please use version 4.0.0 if you are using Angular 6 / Angular 7 / Angular 8 and anything from Cinchy 4.0.0 to Cinchy v4.5.x.
Please use version 4.1.* if you are using Angular 6 / Angular 7 / Angular 8 and Cinchy v4.6.0 and up.
Please use version 4.2.0 and up if you are using Angular 6 / Angular 7 / Angular 8 / Angular 9 / Angular 10 and Cinchy v4.15.1 and up and/or experiencing login issues due to Chrome's new SameSite cookie policies.
Please use version 4.4.0 and up if you are using Angular 7 / Angular 8 / Angular 9 / Angular 10 and Cinchy v4.15.1 and up.
If you are using Angular 5 and a lower version of Cinchy, use version 1.x.x or lower.
In order to use the .getUserPreferences() and .getTranslatedLiterals(guids, debug?) functions in the API (added since version 4.0.0), your Cinchy version should be at least on Cinchy v4.x.x.
Importing the Cinchy Library
From your Angular AppModule
:
...
// Import Cinchy's module and service
import { CinchyModule } from '@cinchy-co/angular-sdk';
@NgModule({
...
imports: [
...
// Import CinchyModule in imports
CinchyModule.forRoot()
],
// Add CinchyModule as one of the providers
providers: [CinchyModule],
...
})
export class AppModule { }
Before Usage
Once CinchyModule is imported, you can use the library through CinchyService. You may use CinchyService anywhere you inject it into.
Before you can make any API calls, you must configure CinchyService and login to Cinchy. In this example, we do it in AppComponent:
...
// Import CinchyService to make API calls and CinchyConfig to configure the service
import { CinchyService, CinchyConfig } from '@cinchy-co/angular-sdk';
...
// Create a config (as a class of CinchyConfig) to be loaded into CinchyService
export const MyCinchyAppConfig: CinchyConfig = {
// The root url of your Cinchy instance
cinchyRootUrl: 'http://my.cinchy.instance.co',
// The url of your Cinchy IdentityServer
authority: 'http://my.cinchy.instance.co/cinchyssocore',
// The redirect url after logging in
redirectUri: 'http://my-app-url/',
// The client id for your applet
clientId: 'my-applet-id',
// (Optional) The redirect url after you logout
logoutRedirectUri: 'http://localhost:3000/',
// (Optional) The requested scopes for the applet (must be permitted for the client)
// You must have openid and id requested
scope: 'openid id email profile roles',
// (Optional) Enable silent refresh
silentRefreshEnabled: true,
// (Optional) (Mandatory if silentRefreshEnabled = true) The silent refresh url
silentRefreshRedirectUri: 'http://localhost:3000/silent-refresh.html'
};
@Component({
...
// Load the MyCinchyAppConfig into CinchyService
providers: [CinchyService, {
provide: CinchyConfig, useValue: MyCinchyAppConfig
}]
...
})
export class AppComponent {
// Inject CinchyService into this component
constructor(private _cinchyService: CinchyService) {
// Redirect to login screen
this._cinchyService.login().then( response => {
console.log('Login Success!');
}).catch( error => {
console.log('Login Failed');
});
}
Enabling Silent Refresh
Silent refresh automatically refreshes your access token every 75% of your token's lifetime.
In order to use silent refresh, you must:
1). Set the silentRefreshEnabled property to true in your CinchyConfig object.
2). Add a silent-refresh.html file into your Angular project. This can be found within the /src/lib/ folder in the repo or copy & paste this:
<html>
<body>
<script>
parent.postMessage(location.hash, location.origin);
</script>
</body>
</html>
3). Within your angular.json file, specify the silent-refresh.html path and file within the "assets" property:
...
"assets": [
"src/favicon.ico",
"src/assets",
"src/silent-refresh.html"
],
...
Silent refresh works by using a hidden iframe to access a url that contains the silent-refresh.html page. This iframe makes a request to the server to retrieve a new access token.
4). Add the silent-refresh url into the "Permitted Login Redirect URLs" field of the "Integrated Clients" table within Cinchy (eg. http://localhost:3000/silent-refresh.html).
Allowing App for Embedment
Apps can be embedded and launched within the Cinchy platfrom.
Before your app can be embedded, you must use the iframe-resizer library within your Angular App. This allows your app to be properly resized within an iFrame when integrated into Cinchy's platform.
The iframe-resizer package is already included in the Cinchy npm package so it installed it within your node_modules.
Simply the iframe-resizer .js files into your project's scripts within .angular-cli.json
:
"scripts": [
"../node_modules/iframe-resizer/js/iframeResizer.min.js",
"../node_modules/iframe-resizer/js/iframeResizer.contentWindow.min.js"
],
Please note that in order for iFrame to properly resize within the Cinchy platform, the height of your outer most elements (a div container for example) needs to have a style height
of auto
.
Example Usage
Once your Angular app is properly set-up and logged into Cinchy, you may start executing queries.
Executing a query and parsing returned data:
const data = [];
const domain = 'My Domain Name';
const query = 'My Query Name';
// Values such as connectionid, transactionid, and parameterized variables in the query
const params = {'@city': 'Toronto'};
this._cinchyService.executeQuery(domain, query, params).subscribe(
response => {
let queryResult = response.queryResult;
// Parses the result data
while (queryResult.moveToNextRow()) {
const this_row = {};
for (const col of queryResult.getColNames()){
this_row[col] = queryResult.getCellValue(col);
}
data.push(this_row);
}
// Printing the result after parsing
console.log(data);
},
error => {
console.log(error);
});
Executing a custom query and parsing returned data:
// CSQL Query
const query = 'SELECT * FROM [DOMAIN].[TABLE NAME]';
// Values such as connectionid, transactionid, and parameterized variables in the query
const params = null;
const data = [];
this._cinchyService.executeCsql(query, params).subscribe(
response => {
let queryResult = response.QueryResult;
// Parses the result data
while (queryResult.moveToNextRow()) {
const this_row = {};
for (const col of queryResult.getColNames()){
this_row[col] = queryResult.getCellValue(col);
}
data.push(this_row);
}
// Printing the result after parsing
console.log(data);
},
error => {
console.log(error);
});
Using Translate API
In order to use the Translation API, you will have to use the getTranslatedLiterals(guids) function and using the returned dictionary to bind the translation text into your view.
Assuming you have CinchyService setup and a user is logged in, follow these steps to get translation working:
1). In your component, import CinchyLiteralDictionary from @cinchy-co/angular-sdk.
import { CinchyLiteralDictionary } from '@cinchy-co/angular-sdk';
2). Find the strings you want translated inside the Literals
table in the Cinchy
domain. Then gather the corresponding guids of the strings and insert them into an array inside your component. Also initialize a CinchyLiteralDictionary object.
export class AppComponent {
literalDictionary: CinchyLiteralDictionary;
guids: string[] = ["27d4314b-adee-4e89-ad7f-2381a21729cf",
"67c7dab0-9a7d-4ec9-88d0-271700c779b4",
"47d9840d-0e09-4693-ae52-c726c5927a3a"];
3). Bind the guids to your component's view.
<div *ngIf="literalDictionary">
<h1>{{ literalDictionary['27d4314b-adee-4e89-ad7f-2381a21729cf'].translation }}</h1>
<p>Translation 1: {{ literalDictionary['67c7dab0-9a7d-4ec9-88d0-271700c779b4'].translation }}!</p>
<p>Translation 2: {{ literalDictionary['47d9840d-0e09-4693-ae52-c726c5927a3a'].translation }}!</p>
</div>
4). Make the API call by passing in the guids into getTranslatedLiterals(guids) and setting dictionary you initialized in the previous step as the response.
export class AppComponent {
literalDictionary: CinchyLiteralDictionary;
guids: string[] = ["27d4314b-adee-4e89-ad7f-2381a21729cf",
"67c7dab0-9a7d-4ec9-88d0-271700c779b4",
"47d9840d-0e09-4693-ae52-c726c5927a3a"];
constructor(private _cinchyService: CinchyService) {
var _this = this;
this._cinchyService.login().then(function() {
_this._cinchyService.getTranslatedLiterals(_this.guids).subscribe(
resp => {
_this.literalDictionary = resp;
},
error => {
console.log('Error getting translations: ', error);
}
);
});
}
}
The translated text will then automatically bind into the view.
API
- CinchyService :
Service
- .login(redirectUriOverride?) ⇒
Promise
- .logout() ⇒
Void
- .getUserIdentity() ⇒
Observable
- .getAccessToken() ⇒
Observable
- .checkSessionValidity() ⇒
Observable
- .executeCsql(query, params, callbackState?, type?) ⇒
Observable
- .executeQuery(domain, query, params, callbackState?) ⇒
Observable
- .openConnection(callbackState?) ⇒
Observable
- .closeConnection(connectionId, callbackState?) ⇒
Observable
- .beginTransaction(connectionId, callbackState?) ⇒
Observable
- .commitTransaction(connectionId, transactionId, callbackState?) ⇒
Observable
- .rollbackTransaction(connectionId, transactionId, callbackState?) ⇒
Observable
- .executeQueries(queryParams, callbackState?) ⇒
Observable
- .getGroupsCurrentUserBelongsTo() ⇒
Observable
- .getTableEntitlementsById(tableId) ⇒
Observable
- .getTableEntitlementsByGuid(tableGuid) ⇒
Observable
- .getTableEntitlementsByName(domainName, tableName) ⇒
Observable
- .getUserPreferences() ⇒
Observable
- .getTranslatedLiterals(guids, debug?) ⇒
Observable
- .login(redirectUriOverride?) ⇒
- Cinchy.QueryResult :
Object
- .convertToObject(key) ⇒
Object
- .getColumns() ⇒
Array<Object>
- .getColNames() ⇒
Array<String>
- .getColCount() ⇒
number
- .getRowCount() ⇒
number
- .moveToNextRow()
- .moveToRow(idx)
- .getCurrentRowIdx() ⇒
number
- .resetIterator()
- .getCellValue(col) ⇒
any
- .getMultiselectCellValue(col) ⇒
Array<String>
- .toObjectArray() ⇒
Array<Object>
- .convertToObject(key) ⇒
- CinchyUserPreference :
Object
- CinchyLiteralDictionary :
Object
- CinchyLiteralTranslation :
Object
CinchyService
Promise
.login(redirectUriOverride?) => Redirects the page to Cinchy's login page.
The login function returns a promise indicating when the user is logged in.
Param | Type | Description |
---|---|---|
redirectUriOverride | string |
Optional. A redirect url after successfully logging in. This overrides the redirect url in the initial CinchyConfig. |
this._cinchyService.login().then( response => {
console.log('Login Success!');
}).catch( error => {
console.log('Login Failed');
});
Void
.logout() => Logs the user out of the session.
Observable
.getUserIdentity() => Retrieves the logged in user's identity information when it is available.
Example: the return object.id is the user's username. object.sub is the user's Cinchy Id.
Observable
.getAccessToken() => Retrieves the access token (string) for the authenticated user when it is available.
Observable<string>
returns
Observable
.checkSessionValidity() => Checks whether or not the access token used to query Cinchy is still valid. If invalid, the application will be unable to call queries on Cinchy.
Observable<{accessTokenIsValid: boolean}>
returns Example Usage
this._cinchyService.checkSessionValidity().subscribe(
success => {
console.log('Session is valid!');
},
error => {
console.log('Session timed out!');
}
);
Observable
.executeCsql(query, params, callbackState?, type?) => Performs a custom CSQL query.
Properties such as "connectionid" and "transactionid" for values received from openConnection() and beginTransaction() can be inserted into the params object.
Observable<{queryResult: CinchyService.QueryResult, callbackState}>
returns Param | Type | Description |
---|---|---|
query | string |
A CSQL query as a string |
params | string |
An object with variables associated or needed with the query (connectionid, transactionid, parameterized values) |
callbackState? | any |
Used for inserting an object of any type to be returned by the function's callbacks |
type? | QueryType |
Used to determine what kind of query to execute (eg. QueryType.VERSION_HISTORY_QUERY would include version history records in the results). By default it uses QueryType.QUERY. See QueryType. |
Observable
.executeQuery(domain, query, params, callbackState?) => Performs a query that's within Cinchy.
Properties such as "connectionid" and "transactionid" for values received from openConnection() and beginTransaction() can be inserted into the params object.
Observable<{queryResult: CinchyService.QueryResult, callbackState}>
returns Param | Type | Description |
---|---|---|
domain | string |
The domain in which the query is in. |
query | string |
The query's name in the domain. |
params | string |
An object with variables associated or needed with the query (connectionid, transactionid, parameterized values) |
callbackState? | any |
Used for inserting an object of any type to be returned by the function's callbacks |
Observable
.openConnection(callbackState?) => Opens a connection with Cinchy for data transactions.
Observable<{connectionId: string, callbackState}>
returns Param | Type | Description |
---|---|---|
callbackState? | any |
Used for inserting an object of any type to be returned by the function's callbacks |
Observable
.closeConnection(connectionId, callbackState?) => Closes a connection with Cinchy for data transactions.
Observable<{connectionId: string, callbackState}>
returns Param | Type | Description |
---|---|---|
connectionId | string |
The connectionid of the connection you want to close. |
callbackState? | any |
Used for inserting an object of any type to be returned by the function's callbacks |
Observable
.beginTransaction(connectionId, callbackState?) => Starts a transaction.
Observable<{transactionId: string, callbackState}>
returns Param | Type | Description |
---|---|---|
connectionId | string |
The connectionid of the connection you want to start a transaction on. |
callbackState? | any |
Used for inserting an object of any type to be returned by the function's callbacks |
Observable
.commitTransaction(connectionId, transactionId, callbackState?) => Commits a transaction.
Observable<{connectionId: string, transactionId: string, callbackState}>
returns Param | Type | Description |
---|---|---|
connectionId | string |
The connectionid of the connection you want to commit the transaction on. |
transactionId | string |
The transactionid of the transaction you want to commit. |
callbackState? | any |
Used for inserting an object of any type to be returned by the function's callbacks |
Observable
.rollbackTransaction(connectionId, transactionId, callbackState?) => Rollback a transaction.
Observable<{connectionId: string, transactionId: string, callbackState}>
returns Param | Type | Description |
---|---|---|
connectionId | string |
The connectionid of the connection you want to rollback the transaction on. |
transactionId | string |
The transactionid of the transaction you want to rollback. |
callbackState? | any |
Used for inserting an object of any type to be returned by the function's callbacks |
Observable
.executeQueries(queryParams, callbackState?) => Executes multiple queries.
Observable<{queryResult: CinchyService.QueryResult, callbackState}[]>
returns Param | Type | Description |
---|---|---|
queryParams | [object] |
An object array. Each object containing variables (domain: string, query: string, params: object, callbackState: any) |
callbackState? | any |
Used for inserting an object of any type to be returned by the function's callbacks |
Observable
.getGroupsCurrentUserBelongsTo() => Retrieves the access control groups the current user belongs to.
Observable<any>
returns
Observable
.getTableEntitlementsById(tableId) => Retrieves a table's entitlements by its id.
Observable<any>
returns Param | Type | Description |
---|---|---|
tableId | string |
The Cinchy Id of the table you want the entitlements of. Can be found when exporting a table model or simply when you view a table in the Cinchy platform, you can see its Id in the url. |
Observable
.getTableEntitlementsByGuid(tableGuid) => Retrieves a table's entitlements by its GUID.
Observable<any>
returns Param | Type | Description |
---|---|---|
tableGuid | string |
The guid of the table you want the entitlements of. Can be found when exporting a table model. |
Observable
.getTableEntitlementsByName(tableDomain, tableName) => Retrieves a table's entitlements by its domain and name.
Observable<any>
returns Param | Type | Description |
---|---|---|
tableDomain | string |
The name of the domain in which the table is in. |
tableName | string |
The name of the table. |
Observable
.getUserPreferences() => Retrieves the current user's preferences (must be logged in).
Observable<CinchyUserPreference>
returns
Observable
.getTranslatedLiterals(guids, debug?) => Retrieves a dictionary of guids that map to their string translations. The language and region of the returned translated text will be based on the current user's language and region preferences inside Cinchy.
Observable<CinchyLiteralDictionary>
returns Param | Type | Description |
---|---|---|
guids | string[] |
A string of guids corresponding to strings that you want translated. |
debug | boolean |
(Optional) A boolean flag. If set to true, the data returned will have more information about the translated text. See CinchyLiteralTranslation |
Cinchy.QueryResult
QueryResult is within the namespace Cinchy
.
It is the object that gets returned whenever you make a query using CinchyService. The object represents the data returned by a query in table form; providing you with functions to iterate through rows and columns to obtain values in each cell.
Think of the QueryResult as a table with a pointer. We nagivate through the table by moving the pointer to each row (default points to -1). In basic useage, we use .moveToNextRow() or .moveToRow() to move the pointer to the next or another row in the table. While pointing to a row, you may use .getCellValue(col) to obtain a cell's value in the row the pointer is located (See example usage).
Object
.convertToObject(key) => This returns the QueryResult as an object with a given column (must have unique values) as the keys mapping to each row.
For example, if you have a QueryResult dataset with columns "Customer Id", "Age", and "Birthday", you may call .convertToObject('Customer Id') and have it return an object with each row mapped to its Customer Id. This way, you may access a row's values based on a Customer Id.
Param | Type | Description |
---|---|---|
key | string |
A column name that contains unique values. |
Array<Object>
.getColumns() => Returns an array of objects definining each column by their name and field type.
The array of objects returned are defined as Array<{columnName: string, type: string}> where columnName
is the name of the column and type
is the data type of the values in the column (e.g. "Int32", "String", "Byte[]", etc.)
Array<String>
.getColNames() => Returns an array of column names as strings.
number
.getColCount() => Returns the number of columns.
number
.getRowCount() => Returns the number of rows.
.moveToNextRow()
Moves the row pointer to the next row.
.moveToRow(idx)
Moves the row pointer to the given row index.
Param | Type | Description |
---|---|---|
idx | number |
The index of the row you want the row pointer to move to. |
number
.getCurrentRowIdx() => Returns the index of the current row the row pointer is at.
.resetIterator()
Moves the row pointer back to index -1.
any
.getCellValue(col) => Returns the cell value of the specified column on the current row.
Param | Type | Description |
---|---|---|
col | string or number |
The name of a column or the index of a column. |
Array<String>
.getMultiselectCellValue(col) => Returns an array of each value in a multiselect field.
When you use .getCellValue(col) on a multiselect column, it returns a string with commas separating each selected value. Using .getMultiselectCellValue(col) allows you to recieve an array instead.
Param | Type | Description |
---|---|---|
col | string |
The name of the multiselect column. |
Array<Object>
.toObjectArray() => Returns an array of objects representing each row in the dataset.
Each key in the object is a column name and maps it to the corresponding cell value. This is useful if you want to use a Array.prototype.map() function on each row.
Object
CinchyUserPreference : CinchyUserPreference is the object returned by the method getUserPreferences(). It is a data structure containing properties of the user's preferences.
interface CinchyUserPreference {
username: string;
name: string;
displayName: string;
emailAddress: string;
profilePhoto: string;
language: string;
region: string;
timeZone: string;
}
Property | Type | Description |
---|---|---|
username | string |
The user's username. |
name | string |
The user's full name. |
displayName | string |
The user's name plus username in parentheses (e.g. "Jane Doe (jane.doe)"). |
profilePhoto | string |
The user's profile photo in base64 encoding. |
language | string |
The user's preferred language's subtag. |
region | string |
The user's preferred region's subtag. |
timeZone | string |
The user's preferred time zone. |
Object
CinchyLiteralDictionary : CinchyLiteralDictionary is the object returned by the method getTranslatedLiterals(guids). It is a dictionary that maps guids to a CinchyLiteralTranslation object (which in turn contains the translation of the guid's corresponding string inside Cinchy).
interface CinchyLiteralDictionary {
[guid: string]: CinchyLiteralTranslation;
}
Property | Type | Description |
---|---|---|
any guid string |
CinchyLiteralTranslation |
Any guid key, maps to a CinchyLiteralTranslation object. |
Object
CinchyLiteralTranslation : CinchyLiteralTranslation is an object used within the CinchyLiteralDictionary dictionary. It is a data structure containing the translation of a literal within Cinchy.
interface CinchyLiteralTranslation {
translation: string;
language: string;
region: string;
defaultText: boolean;
}
Property | Type | Description |
---|---|---|
translation | string |
The translation string. |
language | string |
(only on debug) The language subtag of the translated text. |
region | string |
(only on debug) The region subtag of the translated text. |
defaultText | boolean |
(only on debug) Whether or not the default text was used for the translation text. |
enum
QueryType : QueryType is an enum used within the executeCsql() function. It determines what kind of query is executed.
export enum QueryType {
QUERY = "QUERY",
DRAFT_QUERY = "DRAFT_QUERY",
SCALAR = "SCALAR",
NONQUERY = "NONQUERY",
VERSION_HISTORY_QUERY = "VERSION_HISTORY_QUERY"
}
Type | Description |
---|---|
QUERY | Query that returns only approved data |
DRAFT_QUERY | Query that returns draft values |
SCALAR | Query that returns a scalar value (the first row and first column's value) |
NONQUERY | Non query (eg. inserts, updates, deletes) |
VERSION_HISTORY_QUERY | Query that returns version history |
More Documentaion
See here for more documentation. See here for support.
License
This project is license under the terms of the GNU General Public License v3.0