What's in it for you
This tutorial explains how to set up and use the AppsDB in your experience app using a combination of Showpad developer tools we provide. It assumes you've completed the building your first experience app tutorial.
We're going to make and enrichen our experience app with following offline capabilities:
- get global entries from the AppsDB
- get user entries from the AppsDB
- post user entries to the AppsDB
You can find several notes where we explain tips, tricks, and facts for more advanced developers. You can safely skip this in the tutorial. At the bottom of this page, we provide before and after ZIP files, that show you the starting and ending state of the project.
Note: The current windows app uses IE11 as a render engine. Our app will not work because our syntax will be ES6 flavored.
You need this to succeed
- all the requirements from building your first experience app
- client to execute API requests like https://www.getpostman.com
- latest beta version of our SDK, as our current version will not work at the moment of writing
- appsDB enabled on your domain
Do this step by step
We've prepared a ZIP file where you can copy-paste the index.html, app.js, app.css and config.json over the files in your own project. Now go in your terminal to the directory and start the Showpad development server
showpad experience serve
You will see we divided the content in four blocks:
- search assets.
- displays assets and operate on them.
- write data to a new asset or upload the data to the AppsDB.
- display the captured data from the appsDB
AppsDB concepts
Before we start to implement the AppsDB, let's go over some concepts of this new feature. The AppsDB is a key / value store for Showpad app developers. It can be accessed by leveraging the JavaScript API from an Experience app or by using the REST API.
Store
A store is the top-level object which groups multiple store entries together. A store must be registered before it can be used. This is done by using a POST request to the store endpoint.
Store entry
A store entry is the actual object that holds your data. A store entry is identified by an ID and holds a string as value. Each store entry sits in a Store and has an associated scope.
Scope
A scope is the permission boundary from which an entry is accessible. Currently, there are two scopes. `USER` scope and `GLOBAL` scope.
User Scope
When an entry is created in the `USER` scope that entry is associated with the Showpad user that has created that entry. This means that each user can have its own set of entries within the same store, without colliding with entries from another user. Even though user entries are scoped to a single user it is possible to retrieve all store entries cross-user by using the store entries call. Note that this call requires an additional OAuth2 scope "appsdb*online*integrations" which can be set to your OAuth2 client or by creating a personal access token.
Global Scope
Entries created within the `GLOBAL` scope can be retrieved by all users but can only be created when the requester has the "appsdb*online*integrations" OAuth2 Scope.
Pagination
AppsDB uses cursor-based pagination with an optional limit. When retrieving a large list of user or global scoped entries, we limit the number of entries returned (see REST API documentation). Whenever one of these limits is hit, we return a cursor-string that can be passed to a subsequent request to receive the next page of entries. When no cursor is returned all entries have been retrieved.
Note: When offline use cases matter for the Experience integrating with AppsDB, it is advised to store data that will not change in one store entry or as few possible store entries. For data that is prone to change, put it in the right logical granularity in multiple store entries.
Create stores
For this tutorial, we're gonna create two stores: `TUTORIAL_COMPANIES` & `TUTORIAL_LEADS`. Go to postman (or equivalent) and change **yourdomain** and **personalaccesstoken** of the call.
You can create a personal access token following these steps: In the backend, click on the cogwheel and press integrations. Next, click on the API tokens button, fill in the name and your token will be created. Make sure to keep the token somewhere safe because you will not be able to see it again.
POST https://yourdomain.showpad.biz/api/v3/appsdb/stores/TUTORIAL_COMPANIES https://yourdomain.showpad.biz/api/v3/appsdb/stores/TUTORIAL_LEADS
Use the following headers
{ "Authorization": "Bearer personalaccesstoken", "Content-Type": "application/json" }
You should receive a 201 response meaning our store is created.
Create companies
We now want to add companies to our `TUTORIAL_COMPANIES` store. Go to postman (or equivalent) and change yourdomain, uuid and company name of the call.
PUT https://yourdomain.showpad.biz/api/v3/appsdb/stores/TUTORIAL_COMPANIES/globals/entries/uuid
Add following body to your request (raw)
{ "value": "company name" }
You should receive a 202 response meaning our store is created or updated. Create as many companies as you want. Global stores can be populated by all kinds of external systems: CRM, DAM, PIM,... and could provide the sales rep with the latest data, even when he/she is offline.
For local testing you will need to SHIM your global store. Make a new file called globalStores.json in your root directory and enther following mocked companies:
{ "TUTORIAL_COMPANIES": { "593ffc7f-1cea-4c03-af40-07f5fa1708bc": "Company a", "ca563568-1d3f-4440-8af1-410a025038aa": "Company b", "dd1f0c78-0983-4021-b6b2-da8f1bedeb11": "Company c" } }
While developping you can now access the global entries from the `TUTORIAL_COMPANIES` store.
Display companies
We want our experience app to read out the entered companies. For this, we use the ShowpadLib.getGlobalStoreEntries() method.
1. Replace the `// DISPLAY COMPANIES` comment with following code block inside the displayData() function
window.ShowpadLib.getGlobalStoreEntries('TUTORIAL_COMPANIES', {}, (data) => { document.getElementById('capture_data_company').innerHTML = ''
if (data !== null) { if (data.entries.length > 0) { for (var h = 0; h < data.entries.length; h++) { let parsedCompany = data.entries[h].value let company = document.createElement('option')
company.innerHTML = parsedCompany company.value = parsedCompany
document.getElementById('capture_data_company').appendChild(company) } } } })
2. This will get all `global` entries from the `TUTORIAL_COMPANIES` store. We check if the store exists and if there are entries inside. Next, we loop over the entries and add every entry as an option to our select.
Create lead
We want our experience app to create a lead and save to our `TUTORIAL_LEADS` store in the AppsDB. For this, we use the ShowpadLib.setStoreEntryValue() method.
1. Replace the `// CREATE LEAD` comment with following code block inside the actions() function.
let lead = { 'name': document.querySelector('#capture_data #capture_data_name').value, 'company': document.querySelector('#capture_data #capture_data_company').value } window.ShowpadLib.setStoreEntryValue('TUTORIAL_LEADS', uuidv4 (), JSON.stringify(lead)) ShowpadLib.displayToast({ type: "info", text: "data added to AppsDB" }) setTimeout(() => { displayData() }, 500)
2. This will post our lead with an unique id to the `TUTORIAL_LEADS` store. the value of an entry must always be a string. To have more structured data, you can use **parse** and **stringify** for json data.
3. As you can see we call the displayData afterwards because we want to reflect our leads in the latest block.
Display lead
We want our experience app to display our leads from the `TUTORIAL_LEADS` store in the AppsDB. For this, we use the ShowpadLib.getStoreEntries method.
1. Replace the `// DISPLAY LEADS` comment with following code block inside the actions() function.
window.ShowpadLib.getStoreEntries('TUTORIAL_LEADS', {}, (data) => {
document.getElementById('display_data_table').innerHTML = '' if (data !== null) { if (data.entries.length > 0) { for (var i = 0; i < data.entries.length; i++) { let parsedLead = JSON.parse(data.entries[i].value) let lead = document.createElement('tr') let html = '<td>' + parsedLead.name + '</td>' html += '<td>' + parsedLead.company + '</td>' lead.innerHTML = html document.getElementById('display_data_table').appendChild(lead) } } } })
This will get all `user` entries from the `TUTORIAL_LEADS` store. We check if the store exists and if there are entries inside. Next, we loop over the entries and add every entry as a table row.
Let's ship our app! 🚢
Our app is now ready to be deployed. We'll use the SDK to package our app. Go to your command line tool to the root directory of the app and enter the following command:
showpad experience package
- You will see the SDK validating all of our files and creating a .showpad file.
- You can now go to the backend of your domain and open the channel builder.
- Make a new channel with the type Experience app and select our newly generated .showpad file.
- After uploading, you should see our app but without the JS initialized. This is because we call our init() function in the Showpad.getShowpadApi() call which isn't executed in the preview. This will work in the frontend.
If you click on edit, you will see the structure we defined in the **config.json**. As you can see, you can alter the translations and add, remove tags to our application. - Click on publish experience and wait for the platform to release our app. This can take a minute.
If you now go to the frontend, open our enhanced app and get those leads.
Get leads of all users
So our sales team did a really great job and gathered a lot of new leads. You can now use the REST api to bundle all those leads. Go to Postman (or equivalent) and change yourdomain of the call.
GET https://yourdomain.showpad.biz/api/v3/appsdb/stores/TUTORIAL_LEADS/users/entries
use following headers
{ "Authorization": "Bearer personalaccesstoken", "Content-Type": "application/json" }
You can now use this endpoint to again fuel other systems like your CRM system and close the loop. We hope you see the extreme value and possabilites this feature brings. Dont hassle to ask more information in the community!
Endnote
You can find the completed version below to compare differences with your codebase.
The developer pages are your go-to source while developing experience apps.
We welcome you to ask your questions in the community part, so fellow developers can answer your questions and everyone can learn from everyone.
Happy coding!