JavaScript API functions

Switch to

JavaScript API version 2

Changelog

Support for Collections was added. This release also adds functionality that provides access to the Showpad Api and the Salesforce Api.

Deprecated methods from v1:

Usage

The methods listed below are all available on the window.ShowpadLib object after page load. Simply call the desired method with the correct parameters.

When window.ShowpadLib is created and ready to go, the method window.onShowpadLibLoaded() will be called (if it exists).

Have a look at the examples to get some more context.

Methods

All methods returning a boolean (all methods except for getUserInfo) will return true when the call was executed successfully and return false when something went wrong. The method returns false when a required parameter was not set or when the method was called again before the previous method was completed.

getUserInfo

Returns the information of the active user.

const userInfo = window.ShowpadLib.getUserInfo();

// userInfo will look like this:
const userInfo = {
    email: 'user@company.com',
    id: '123',
    user_name: 'user@company.com',
    full_name: 'Firstname Lastname'
};

getCollections

Invokes the callback function with a list of collection data ([{ id, name }]) or null when something went wrong.

if (window.ShowpadLib.getCollections(callbackFn)) {
    // Call went through, callbackFn will be called.
}
else {
    // Something went wrong
}

function callbackFn (collections) {
    if (collections) {
        // Collections might look like this:
        const collections = [
                {
                    id: '1',
                    name: 'Collection Name 1',
                },
                {
                    id: '2',
                    name: 'Collection Name 2'
                }
            ];
    }
    else {
      // null was returned, something went wrong
    }
}

openCollection

Shows a modal view with the contents of the collection. This view allows for the collection to be shared

const collectionId = '...' ;
if (window.ShowpadLib.openCollection(collectionId)) {
    // Modal will be opened
}
else {
    // Something went wrong
}

createCollection

Creates a new collection with the specified name, will invoke the callback function with the id of the new collection or null when an error occured

const name = 'My Collection Name';
if (window.ShowpadLib.createCollection(name, callbackFn)) {
    // Call went through, callbackFn will be called.
}
else {
    // Something went wrong
}

function callbackFn (collectionId) {
    if (collectionId) {
        // Do something with collection id
    }
    else {
       // Something went wrong
    }
}

addAssetsToCollection

Shows the modal which prompts the user the select the collection to add the assets to.
Will call the callback method with the id of the collection the assets were added to or null if the flow was canceled or an error occured

const assets = [];
assets.push('asset1-slug');
assets.push('asset2-slug');
if (window.ShowpadLib.addAssetsToCollection(assets, callbackFn)) {
    // Call went through, modal will be shown.
    // callbackFn will be called
}
else {
    // Something went wrong
}

function callbackFn (collectionId) {
    if (collectionId) {
        // Assets were added to the collection with provided collectionId
    }
    else {
       // Something went wrong or the user canceled the flow or
       // none of the given asset-slugs were found.
    }
}

addAssetsToCollectionWithId

Will add the given assets to the collection with the given id. If the collection does not exist, nothing will happen.

const collectionId = '...';
const assets = ['asset1-slug', 'asset2-slug'];
if (window.ShowpadLib.addAssetsToCollectionWithId(collectionId, assets, callbackFn)) {
    // Call went through, callbackFn will be called
}
else {
    // Something went wrong
}

function callbackFn (collectionId) {
    if (collectionId) {
        // Assets were added to the collection with provided collectionId
    }
    else {
       // Something went wrong or the user canceled the flow
    }
}

clearCollection

Removes all the items from the given collection

const collectionId = '...';
if (window.ShowpadLib.clearCollection(collectionId)) {
    // Call went through, items will be cleared
}
else {
    // Something went wrong
}

getShowpadApi

Invokes the callback function with an object with the required information to do an HTTP request to the Showpad API.

If the Showpad API returns a 401, it means your access token has expired, and you’ll need to request a new one. Do this using the refreshShowpadApi() method.

if (window.ShowpadLib.getShowpadApi(callbackFn)) {
    // Call went through, callbackFn will be called
}
else {
    // Something went wrong
}

function callbackFn (apiConfig) {
    if (apiConfig) {
        // apiConfig can look like this:
        const apiConfig = {
            accessToken: 'xyz',
            url: 'https://subdomain.showpad.biz', // no trailing slash
            error: null // or a string with the actual error
        };

        if (apiConfig.accessToken && apiConfig.url) {
            // Do an api-call
        }
        else if (apiConfig.error) {
            if (apiConfig.error === 'unavailable') {
                // no api key available
            }
            else {
                // something else went wrong
            }
        }
        else {
            // Something went wrong
        }
    }
    else {
       // Something went wrong or the user canceled the flow
    }
}

refreshShowpadApi

This method will refresh the Showpad access token and call the callback function with the same object as the getShowpadApi call

function doApiCall (url, config) {
    fetch(url, config)
            .then(response => {
                if (response.status < 200 || response.status >= 400) {
                    const error = new Error();
                    error.statusCode = response.status;
                    throw error;
                }
            })
            .catch(onApiCallFailed);
}
function onApiCallFailed (error) {
    if (error.statusCode === 401) {
        // Unauthorized, let's refresh the token
        refreshToken(url, config);
    }
}

function refreshToken (url, config) {
    if (window.ShowpadLib.refreshShowpadApi(apiConfig => {})) {
        // Call went through, callbackFn will be called
    }
    else {
        // Something went wrong
    }

    function callbackFn (apiConfig) {
        if (apiConfig) {
            // apiConfig can look like this:
            const apiConfig = {
                accessToken: 'xyz',
                url: 'https://subdomain.showpad.biz', // no trailing slash
                error: null // or a string with the actual error
            };

            if (apiConfig.accessToken && apiConfig.url) {
                // Refresh succeeded, retry the failed call.
                config.headers['Authorization'] = `Bearer ${apiConfig.accessToken}`;
                doApiCall(url, config);
            }
            else if (apiConfig.error) {
                if (apiConfig.error === 'unavailable') {
                    // no api key available
                }
                else if (apiConfig.error === 'expired') {
                    // Refresh Token has expired, no further calls can be made.
                }
                else {
                    // Something went wrong
                }
            }
            else {
                // Something went wrong
            }
        }
        else {
           // Something went wrong
        }
    }
}

getSalesforceApi

Invokes the callback function with an object with the required information to do an HTTP request to the Salesforce API.

If the Salesforce API returns a 401, it means your access token has expired, and you’ll need to request a new one. Do this using the refreshSalesforceApi() method.

if (window.ShowpadLib.getSalesforceApi(callbackFn)) {
    // Call went through, callbackFn will be called
}
else {
    // Something went wrong
}

function callbackFn (apiConfig) {
    if (apiConfig) {
        // apiConfig can look like this:
        const apiConfig = {
            accessToken: 'xyz',
            url: 'https://login.salesforce.com', // no trailing slash
            error: null // or a string with the actual error
        };

        if (apiConfig.accessToken && apiConfig.url) {
            // Do an api-call to Salesforce
        }
        else if (apiConfig.error) {
            if (apiConfig.error === 'unavailable') {
                // no Salesforce access token available
                // Possibly, the user is not connected to Salesforce.
            }
            else {
                // something else went wrong
            }
        }
        else {
            // Something went wrong
        }
    }
    else {
       // Something went wrong or the user canceled the flow
    }
}

Particularities with the Salesforce API and HTML Content

To call an api on a different domain (eg. “https://login.salesforce.com”), that service needs to have CORS enabled. More info about CORS or (Cross-Origin Resource Sharing) can be found here .

Salesforce has a specific settings-page to enable specific domains for your Salesforce instance. Salesforce requires this to be an “https://”-url. The problem is that your HTML Content is also rendered in our mobile apps, and they don’t use an “https://”-scheme, but something specific for the platform (eg. “ms-appx-package://” on Windows).

So calling the Salesforce API directly from your HTML Content, will probably result in a CORS error by Salesforce.

To circumvent this, we suggest to proxy all api-calls to Salesforce through an iframe. This iframe would link to a webpage hosted on a CORS-enabled domain. The javascript in the HTML Content would just call some javascript in that iframe, which would send it through to Salesforce and send the response back. The communication between the HTML Content and the iframe needs to happen with “postMessage” https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage.

The diagram below might make things more clear.

refreshSalesforceApi

This method will refresh the Salesforce access token and call the callback function with the same object as the getSalesforceApi call.

function doSalesforceApiCall (url, config) {
    fetch(url, config)
            .then(response => {
                if (response.status >= 200 && response.status < 300) {
                    return response;
                }
                const error = new Error();
                error.statusCode = response.status;
                throw error;
            })
            .catch(onSalesforceApiCallFailed);
}
function onSalesforceApiCallFailed (error) {
    if (error.statusCode === 401) {
        // Unauthorized, let's refresh the token
        refreshSalesforceToken(url, config);
    }
}

function refreshSalesforceToken (url, config) {
    if (window.ShowpadLib.refreshSalesforceApi(apiConfig => {})) {
        // Call went through, callbackFn will be called
    }
    else {
        // Something went wrong
    }

    function callbackFn (apiConfig) {
        if (apiConfig) {
            // apiConfig can look like this:
            const apiConfig = {
                accessToken: 'xyz',
                url: 'https://login.salesforce.com', // no trailing slash
                error: null // or a string with the actual error
            };

            if (apiConfig.accessToken && apiConfig.url) {
                // Refresh succeeded, retry the failed call.
                config.headers['Authorization'] = `Bearer ${apiConfig.accessToken}`;
                doApiCall(url, config);
            }
            else if (apiConfig.error) {
                if (apiConfig.error === 'unavailable') {
                    // no Salesforce access token available
                }
                else if (apiConfig.error === 'expired') {
                    // Salesforce Refresh Token has expired, no further calls can be made.
                }
                else {
                    // Something went wrong
                }
            }
            else {
                // Something went wrong
            }
        }
        else {
           // Something went wrong
        }
    }
}