Getting started
Shapes SDK exists t to provide clear methods for requesting and storing profile data, managing the state of this data and emitting events to subscribed components, on update. It also handles all caching of data and merging of resource requests, to avoid unecessary requests;
Installing
Using npm:
$ npm install @omneo/shapes-sdk
Using yarn:
$ yarn add @omneo/shapes-sdk
Using CDN:
<script type="text/javascript" src="https://cdn.omneo.io/shapes-sdk/shapes.sdk.js"></script>
When including ShapesSDK from the CDN, the library will be attached to the window and accessible at window.ShapesSDK. When including from npm/yarn ShapesSDK can be used via ES6 import or ES5 require:
import ShapesSDK from '@omneo/shapes-sdk'
var ShapesSDK = require('@omneo/shapes-sdk')
ShapesSDK.init()
Returns a client
object
When initializing the ShapesSDK, the init function requires an Omneo ID (or proxy) url url
and an Omneo ID token token
. The constructor also allows an optional flag to be set, to enable console logging, for debugging logging
var shapesClient = ShapesSDK.init({
url: 'https://api.{environment}.getomneo.com/id',
token: '{omneo_id_token}',
logging: true
})
Some implementations may use a proxy url, please check with your Omneo implementation partner to confirm this.
Omneo ID token must first be generated by a secure server process. If you are using an Omneo eCommerce plugin, the token will be generated on login and added to a metafield
Client Object
One initialised the shapesClient
object exposes a number of methods for retrieving cached profile data, handling requests to Omneo and subscribing to state updates.
All methods interact with the client data state, which follows this structure:
{
"client_id": uuid,
"loading": boolean,
"profile": {
"init": true,
"error": false,
"loading": false,
"data": {
"id": "8e697f6b-533d-4837-8680-e7c6b3cde9f0",
"first_name": "John",
"last_name": "Smith",
...
}
}
}
Methods
.find()
Traverses and returns value from the shapes data state, using a path in dot .
format.
Arguments
path
- Dot notation path to data in state
Returns
Value from existing shapesClient
state. If no value is found, null
is returned.
Note
This method is not responsible with fetching new data. When shapesClient
loads, it will pull all cached data and a fresh set of top level profile
data. If an endpoint such as transactions
is required, register this with the hydrate()
method below, which will then fetch from the Omneo API.
Example
let transactions = shapesClient.find('transactions'); // Get all
transactions
let combined_balance = shapesClient.find('balances.combined_balance_dollars') // Get first transaction by index
let loading = shapesClient.find('loading'); // Get loading state
let state = shapesClient.find(); // Get shapes state
.hydrate()
Registers that shapesClient
must retrieve the given endpoint. If the data has not already been fetched, shapesClient
will get this data from Omneo and merge it into the client state. Once initialized, shapesClient
will then emit the relevant shapes.{endpoint}.ready
event.
Arguments
path
- Dot notation path to endpoint
Returns
true
if there were no exceptions. All updates should be watched for through the .on()
method
Example
shapesClient.hydrate('transactions')
shapesClient.hydrate('profile')
shapesClient.hydrate('lists')
.on()
Allows you to add handlers to a shapesClient
event. You can register multiple handlers to the same event, by calling this function for each. Each time the event with event_name
is triggered, all handlers for this name will be called with event data passed as an argument.
For available events, see Events
Arguments
event_name
- Dot notation event namehandler
- Function with singledata
argument, to be executed on event
Returns
The value of that event's relevant endpoint. Note that list endpoints are transformed into keyed objects for ease of state management.
Example
let handler = function(data){
console.log(data);
};
let profile = shapesClient.on('profile.update', handler);
// console.log
// {
// "init": true,
// "error": false,
// "loading": false,
// "data": {
// "id": "8e697f6b-533d-4837-8680-e7c6b3cde9f0",
// "first_name": "John",
// "last_name": "Smith",
// ...
// }
// }
.off()
Allows you to remove a handler for a shapesClient
event.
For available events, see Events
Arguments
event_name
- Dot notation event namehandler
- Function with singledata
argument, to be executed on event
Returns
true
if event listener was unregistered correctly
Example
let handler = function(data){
// Do something with data
};
shapesClient.off('profile.update', handler);
.dispatch()
Dispatches an action directly to the internal store to manually manage state. The internal store reducer handles a number of action types.
[resource].update
Will merge the payload into the top level resources. Special consideration is given to data
so it will be merged and not overwrite the existing state. Ensure that for resources such as transactions
the array of items has been converted to an object with id
as key.
{
"type": "profile.update",
"payload": {
"error": false,
"data": {
"first_name": "John"
}
}
}
[resource].add
An alias of update
that is used when adding new items to resource lists, such as rewards
or transactions
[resource].remove
Removes a key from the {resource}.data
object by specifying the key in the payload
{
"type": "transaction.remove",
"payload": {
"id": "5"
}
}
[resource].set
Merges the payload against the whole state object. Special provisions are not made for data
and anything included in the set
payload will overwrite the existing state. This is especially useful if you are managing the whole state manually.
{
"type": "lists.set",
"payload": {
"init": true,
"loading": false,
"data": {
"5": {...},
"27": {...}
}
}
}
[resource].load
Sets the loading state of a resource. This does not merge any other payload keys. This is useful for setting loading: true
before a http request etc.
{
"type": "profile.load",
"payload": {
"loading": true
}
}
[resource].reset
Resets the resource back to the initial state of the reducer. Useful for clearing if cached data is malformed or if there has been an error.
{
"type": "lists.reset",
}
Arguments
Dispatch receives a single action object, with type
and payload
keys to update the state.
type
- Action type, using.
separator to designate the resource. eg.profile.set
payload
- Object containing key/values to update in state. Refer to the action types for examples and accepted keys for eachtype
Returns
undefined
Example
shapesClient.dispatch({
type: 'profile.update',
payload: {
data: {
first_name: "John",
last_name: "Smith",
email: "john@example.com"
}
}
})
shapesClient.dispatch({
type: 'transacitons.add',
payload: {
data: {
"5":{
id: 5,
items: [...]
}
}
}
})
shapesClient.dispatch({
type: 'lists.remove',
payload: {
data: {
id: 5
}
}
})
Requests
Shapes provides methods for making authenticated requests to all profile endpoints in Omneo. In addition, the shapes requests methods allow for automatic updating of top level profile objects such as transactions
Note
Currently the Request methods do not support automatic state updates of deeply nested objects, such as items within a list eg. lists.1.items.4
Methods
// GET
shapesClient.get(path, params, updateState)
// POST
shapesClient.put(path, data, updateState)
// PUT
shapesClient.post(path, data, updateState)
// DELETE
shapesClient.delete(path, false, updateState)
Arguments
path
- Dot notation path to endpointdata
- Body payload for PUT and POST requestsparams
- GET parameters, used to filter and paginate browse/list requestsupdateState
- A boolean flag automatically merge request response into the state and emit update events to all subscribers.
Returns
A JavaScript Promise object. Once resolved, this method will return the value of that endpoint.
Example
shapesClient.get('profile').then(response=>{
// Do something with profile data
})
shapesClient.post('profile', { first_name: "James" }, true).then(response=>{
// Profile object with updated "new_name" field
})
shapesClient.put('lists.6', { id: 2, title: 'New List Item' }, true).then(() => {
// Added new item to a list with the id of 6
})
shapesClient.delete('list.6', true).then(response => {
// Delete entire list with id of 6
// response.status = 204 no content
})
Events
As the shapesClient
manages all state and requests internally, it exposes a number of events to keep subscribed components up to date. These events are emitted through 2 differend streams. The first is to subscribers
of shapesClient.on('{event_name}')
and the second is to the native browser js Event()
handler.
Note: In addition to the methods below, the shapesClient
also emits all events to the document
as custom named events.
Event structure
Events are defined by an event type and payload. Shapes will emit general events for when the client is initialized and for any state update. It will also emit events for profile.ready
and profile.update
as well as ready
and update
events for all individual endpoints. Events will include the UUID for the shapesClient
as well as a loading indicator to confirm if an update
event represents a loading state for that state object.
Event types
- shapes.ready
- shapes.update
- shapes.{endpoint}.ready
- shapes.{endpoint}.load
- shapes.{endpoint}.update
shapes.{event_type}
{
"client_id": uuid,
"profile":{
"init": true,
"error": false,
"loading": false,
"data": {...}
},
"transactions":{
"init": true,
"error": false,
"loading": false,
"data": {...}
},
...
}
shapes.{resource}.{event_type}
{
"init": true,
"error": false,
"loading": false,
"data": {
"id": "8e697f6b-533d-4837-8680-e7c6b3cde9f0",
"first_name": "John",
"last_name": "Smith",
...
}
}