LogoLogo
What's NewDeveloper CommunitySupportStatus
  • 🚀Get Started
    • What is JourneyApps Platform?
    • Tutorial: Build your First App
      • 1. Introduction
      • 2. Create a new App
      • 3. OXIDE IDE Overview
      • 4. Hello World app
      • 5. The Data Model
      • 6. View Components
      • 7. Queries and Data Sync
      • 8. Simple Navigation
      • 9. View Stack
      • 10. Input Validation
      • 11. View Parameters
      • 12. Data Manipulation
      • 13. Responsive Apps
      • 14. Styling
      • 15. Lists
      • 16. GPS Capturing
      • 17. Relationships
      • 18. Multiple User Roles
      • 19. Deployment and Users
      • 20. Version Control
      • 21. CSV and APIs
      • 22. Conclusion
    • JourneyApps Platform Fundamentals
      • Creating a New App
        • Git-enabled Apps
      • What are Views?
      • What is the Data Model?
      • JourneyApps Syntax Basics
      • Access the Database (DB)
        • Manipulate DB Objects
        • Query DB Objects
      • View Navigation
        • Deep Linking
      • CloudCode Overview
      • OXIDE (Online IDE)
  • 💻Build your App
    • JourneyApps Syntax
      • Syntax Basics
      • Access the DB
      • View Navigation
      • Async & Await
      • TypeScript Apps (Beta)
        • runtime-build package
        • TypeScript App Troubleshooting
      • What's New in V4
        • Updating to the V4 API
    • Configure your Data Model
      • What is the data model?
      • Reference: model
        • field
        • belongs-to
        • has-many
        • index
      • Data Rules
        • Data Buckets
        • Sync Rules - Limit data synced to devices
        • Data ACLs - Limit access to data
        • Real-world example for Data Rules
        • ❔FAQs
        • Migrate to Data Rules
      • App Indexes
      • Webhooks
    • UI Components
      • All UI Components
        • actionSheet
        • Attachments
        • button
        • button-group
        • capture-coordinates
          • marker
          • marker-query
        • capture-file
        • capture-photo
        • capture-signature
        • card
          • accent
          • action
        • columns
          • column
        • component
        • context-menu
          • divider
          • item
        • CSV
        • date-input
        • datetime-input
        • dialog
          • body
        • display-3d-model
          • 📖display-3d-model Guides
            • Guide 1: Initialize and layout a 3D model in a view
            • Guide 2: Control playback position
            • Guide 3: Troubleshooting controls
        • display-coordinates
        • display-file
        • display-image
        • display-photo
        • display-signature
        • heading
        • html
          • HTML Advanced Topics
          • ❔HTML FAQs
          • 📖Guide: HTML & JourneyApps iFrame Client
        • icons
        • info
        • info-table
          • row
        • journey.photos (capture multiple photos)
        • JourneyPrinter (print PDFs)
        • grid
          • cell
          • 📖grid Examples
        • list
          • list-item
            • accent
            • asset
            • pills
              • pill
            • action
        • multiple-choice-checklist
        • navigation (Navigation drawer)
          • general-section
            • item
          • section
            • item
              • item
          • ❔navigation FAQs
        • notification
        • object-dropdown
        • object-list
          • action
        • object-repeat
        • object-table
          • action
          • column
            • action
            • edit-boolean
            • edit-date
            • edit-datetime
            • edit-integer
            • edit-number
            • edit-select
            • edit-text
            • edit-time
            • edit-typeahead
              • action
            • header-action
          • column-group
          • empty-action
          • 📖object-table Guides
            • Actions
            • Cell callouts
            • Column groups
            • Columns
            • Controlled object-table
            • Controls
            • Copy & paste data
            • Edit cells
            • Filters
            • Frozen columns
            • Fullscreen object-table
            • Mode
            • State
            • Styles
        • optionList
        • PhotonSync (transfer data offline)
        • power-bi
          • 📖Guide: PowerBI Embedding
        • scan-barcode
        • shortcut
        • sidebar
        • single-choice-dropdown
        • single-choice-radio
        • template
        • text-input
        • time-input
        • toggle
        • view
      • JS/TS Events
      • Show / Hide UI Components
      • View Templates
      • XML Fields (Attributes)
        • align-content
        • align-controls
        • align-label
        • bind
        • clear-button-visibility
        • control-order
        • disabled
        • error-message
        • icon-position
        • id
        • hide-if
        • modifier-text
        • label
        • label-case
        • label-color
        • on-change
        • on-press
        • placeholder
        • required
        • show-if
    • JS / TS APIs
      • Attachment
      • Bluetooth (Beta)
      • Broadcast
      • component
      • CSV
      • DB
      • HardwareBarcode
      • journey
        • journey.config
        • journey.container
        • journey.device
        • journey.diagnostics
        • journey.dialog
        • journey.files
        • journey.hardware
        • journey.photos
        • journey.runtime
        • journey.sensors
        • journey.viewStack
      • JourneyPrinter
      • KeyboardBarcode
      • LocalDB
      • NFC
      • OnlineDB
      • PhotonSync
      • SerialPort
      • ShortcutManager
      • TCPSocket
      • user
    • Extend your App with Custom Code
      • App packages
        • App packages overview
        • PDF report package
        • TypeScript library & unit tests
        • Manage External Dependencies
      • Custom HTML
    • Style & Customize your App
      • Style & configure UI components
        • Overview
        • Understand extendable themes
        • Use themes on a view
        • Theme specific components on a view
        • Examples
        • Debugging
        • ❔FAQs
      • Change your App Font
      • Custom Branding
        • Custom Container Features
        • Special Requirements for iOS Containers
    • Integrate your App
      • Backend integrations with CloudCode
      • Barcode Scanning
        • Barcode Scanning using Keyboard Emulation
        • Hardware Barcode Scanning
        • scan-barcode
      • Bluetooth Low Energy (BLE)
      • Broadcast API
      • HTTP requests (Fetch API)
      • JourneyApps Print (Android)
      • Maps and navigation
      • NFC
      • Opening external links/apps
      • Serial Port
      • TCP Sockets
    • Design Intuitive Apps
      • UX Guidelines
      • Write Effective Copy
  • 📱App Features
    • RealWear® Voice Control
      • Automatic Voice Commands
        • Automatic Voice Commands - Advanced
      • Manual Voice Commands
    • App, Runtime and Container Updates
    • Batch Operations (App)
    • Call JS/TS Functions from XML
    • Capture GPS Locations
    • Push Notifications
    • Translations
    • XML Format Strings
    • Webhooks (External)
  • 🌐CloudCode
    • CloudCode Overview
    • Trigger a CloudCode Task
      • Trigger CC with a Schedule
      • Trigger CC via a Webhook
      • Trigger CC from an App
      • Trigger CC from Another Task
      • Trigger CC via HTTP
    • Attachments in CloudCode
    • Timezones
    • Advanced CloudCode Topics
      • Access Multiple DBs in CloudCode Tasks
      • Batch API (CloudCode)
      • CloudCode Dependencies
      • Configure HTTPS in CloudCode
      • Deployment environment variables
      • Local CloudCode Development
      • PDF Reports using CloudCode
      • Shared CloudCode Tasks
      • Translations in CloudCode
  • 📥Backend API
    • Introduction
    • API Reference
      • Retrieve All Objects
      • Query Objects
      • Sort Results
      • Limit and Skip
      • Count Objects
      • Create a New Object
      • Retrieve a Single Object
      • Update a Single Object
      • Delete a Single Object
      • Batch Operations (v4 API)
      • Oplog API
      • Retrieve the App Data Model
      • Manage App Users and Sessions
      • Field Representation
      • Error Responses
    • API Limits
    • Update to the V4 API
  • ⚙️Technical
    • Data Synchronization Priority
    • Device Diagnostics
    • JSON1 Query Engine
    • Improve App Performance
    • Security Measures
    • Supported Platforms
      • Web Container
      • Windows Installer
    • Domain Whitelist
  • 🖥️OXIDE
    • Get started with OXIDE
      • OXIDE Overview
      • Components of OXIDE
    • Configure Testing Deployments
    • Edit and Manage Files
      • How to Navigate to a Function
      • Manage External Dependencies
    • Create and Manage App Containers
    • Debugging & Troubleshooting
      • Common Troubleshooting Pointers
      • App Diagnostics Reports
      • Build Logs
    • OXIDE Workspaces
      • OXIDE Trees
  • ❕Deprecated Features
    • Deprecated Features and Components
Powered by GitBook
On this page
  • Single, Common Data Model
  • Syntax
  • A Real-World Example
  • Create the punch List App & Link Test Device
  • Open up the Data Model Workspace
  • Building the Data Model
  • Add a Model
  • Add Some Fields to the Object Type
  • Display Format
  • That's It!
  1. Get Started
  2. Tutorial: Build your First App

5. The Data Model

Previous4. Hello World appNext6. View Components

Last updated 2 years ago

The Data Model defines the structure of the database that will be used by your app, and should be determined by the nature and structure of the data that is to be accessed and used in the app. JourneyApps supports fully relational data models:

  • You define the Models that are required in the app

  • For each model you define various Fields, each with a specific type (for example a name field of type text to store the Name of the object, or a created_at field of type datetime to store the exact date and time the object was created)

  • You also define the Relationships between Models, which are used to link related models (for example a one-to-many relationship between cart and item, i.e. a cart can have many items linked to it)

  • You can also define special fields for default display values, app indexes, and for configuring webhooks

These then describe the structure and nature of data that can be stored in each model. An instance of a model is called an object, and each object has a unique, system generated, identifier called the id of the object.

Learn more about relational databases

Understanding the basics of relational databases will simplify the design of your app's data model significantly. If you are not familiar with relational databases, we suggest that you read more about them using online resources.

Single, Common Data Model

A valuable feature of JourneyApps is that the Data Model for an app only needs to be defined once, in OXIDE, and is then used throughout the entire JourneyApps Cloud. Once you've defined your Data Model it will be used by the application, the Backend, the API and all other related JourneyApps services.

Syntax

This is an example of a Data Model for a simple asset management app. It contains two models, asset and building. Most of the data collected are for the assets, and a building can have many assets - a one-to-many relationship.

schema.xml
<data-model>
  <model name="asset" label="Asset">
    <field name="make" label="Make" type="text:name"/>
    <field name="model" label="Model" type="text:name"/>
    <field name="serial_number" label="Serial Number" type="text:number"/>
    <field name="description" label="Description" type="text"/>
    <field name="picture" label="Picture" type="photo"/>
    <field name="condition" label="Condition" type="single-choice">
      <option key="good">Good</option>
      <option key="ok">Ok</option>
      <option key="bad">Bad</option>
    </field>

    <belongs-to model="building"/>

    <display>{make} {model} {serial_number}</display>
  </model>

  <model name="building" label="Building">
    <field name="name" label="Name" type="text:name"/>

    <has-many model="asset" name="assets"/>

    <display>{name}</display>
  </model>
</data-model>

A Real-World Example

Real-World Example: Construction Punch List

In the construction and real estate industries, a "punch list" is often created to keep inventory of the things that an owner or tenant isn't happy with when a building project is finished or when they move into a new leased building.

Things that could appear on a punch list include: Cracks in ceiling and walls, skirting boards that aren't properly affixed, uneven or unfinished drywall, crooked fixtures, loose wiring, poor insulation, leaking pipes, etc.

A great alternative to compiling and maintaining a punch list manually is to build a mobile app on JourneyApps that allows capturing and centralized tracking of punch list items electronically. Photos, notes and GPS locations can easily be attached to each item, and it is easy to export the punch list and send it to someone, or to build a web portal that pulls data from to the JourneyApps API where stakeholders can browse the punch list.

Create the punch List App & Link Test Device

We will now create a new blank app to start building the punch List app.

Important: Start Again with a New App.

Open up the Data Model Workspace

After creating the new Punch List app, go to the Data Model Workspace. You should see the following:

What you are seeing is your data model xml code, also called the schema, in the right editor pane, the ERD for your current data model rendered in the left editor pane, and the Data Model panel on the left of the screen. Notice that any new JourneyApps application that you create starts with two models in the Data Model, user and push_notification. The user model is used to store information about the end users of your app and is required for most apps. By default, the user model has one field, name, of type text which stores the user's name. The default push_notification model is used and pre-configured to allow you to easily create and send Push Notifications to your app users, but more about that at a later stage.

Your schema.xml file should contain the following:

schema.xml
<?xml version="1.0" encoding="UTF-8"?>
<data-model>
    <!-- Do not remove this - it is used to store information about your app's users: -->
    <model name="user" label="User">
        <field name="name" label="Name" type="text:name"/>

        <display>{name}</display>
    </model>

    <!-- Used for Push Notifications - to send a push notification, create a 'push_notification' object -->
    <!--                               and specify the recipient in the 'belongs to user' relationship -->
    <!-- For more details, refer to: http://resources.journeyapps.com/v4/push-notifications -->
    <model name="push_notification" label="Push Notification">
        <field name="message" label="Message" type="text" />
        <field name="received_at" label="Received At" type="datetime" />
        <field name="created_at" label="Created At" type="datetime" />

        <belongs-to model="user" />
        <display>{message} ({user})</display>
        <notify-user message="{message}" received-field="received_at" recipient-field="user"/>
    </model>

    <!-- ADD MODELS HERE: -->

</data-model>

Whenever you modify your Data Model XML code (the schema.xml file), the ERD will be updated automatically.

Building the Data Model

Let's look at what the requirements are for our Punch List app's Data Model

App Design: Construction Punch List. The simplest Data Model for our Punch List App is to have a collection of punch list items, each with a photo, comments and status (Open/Closed). Our app will then allow users to capture new punch list items that are initially "Open", which they can then later change to "Closed" when the punch has been taken care of.

Add a Model

Therefore, we need to add a new model to our Data Model named item. Below "ADD MODELS HERE" in the XML, type model and you should see an auto-complete suggestion underneath your cursor. Insert the auto-complete suggestion by pressing return/enter (If there is only one auto-complete suggestion it will be selected by default and so there is no need to select it first). If you do not see the auto-complete suggestion, or you have clicked-away from it, simply get your cursor back to the end of the word you were typing and press Ctrl + spacebar.

For our newly added model, enter item as the name of the model, and Item as the label (the name="" attribute is what is used to refer to the model in your code, whereas the label="" attribute is a human-readable label for the model that is used in other parts of the platform).

<model name="item" label="Item">
    <field name="" label="" type="" />

    <display></display>
</model>

Add Some Fields to the Object Type

Now populate your first data model field, comments, and specify its type as text.

<model name="item" label="Item">
    <field name="comments" label="Comments" type="text" />
  
    <display></display>
</model> 

Next we want to add an attribute to store the photo of the punch list item. Type photo on the next line and once you see the auto-complete suggestion for a photo field hit return/enter to insert. This will give you a field for a photo and now you just need to add the name and the label. Fill in photo as the name and Photo as the label.

<model name="item" label="Item">
    <field name="comments" label="Comments" type="text" />
    <field name="photo" label="Photo" type="photo" />

    <display></display>
</model>

Pro Tip: Jump between _XML_** input fields**

You can use Ctrl + . and Ctrl + , to move your cursor to the next and previous input fields in any xml code in JourneyApps. Try it now in your Data Model (schema.xml)

<model name="item" label="Item">
    <field name="comments" label="Comments" type="text" />
    <field name="photo" label="Photo" type="photo" />
    <field name="status" label="Status" type="single-choice">
        <option key="Open">Open</option>
        <option key="Closed">Closed</option>
    </field>
    <display></display>
</model>

Display Format

The last thing we need to customize is how our item objects will be displayed by default (e.g. when they are shown in a list). This is specified using the <display></display> tag that you can see below your fields. Inside the display tags we can make use of String interpolation. In xml string interpolation of variables/placeholders is accomplished using curly brackets. So, here you can specify which field values should be included when the object is displayed. Field names are wrapped in curly brackets, and you can also include some raw text. Let's make our punch List items display their Status, followed by a hyphen and then their Comments:

<display>{status} - {comments}</display>

That's It!

We've now created the first version of the Data Model for our Punch List app. This will now automatically be used to determine the structure of the "database" in your app and elsewhere throughout the JourneyApps ecosystem (e.g. for storing your app's data in the cloud, exposing that data through the backend API, etc.).

At this time your Data Model (schema.xml) should like like this.

schema.xml
<?xml version="1.0" encoding="UTF-8"?>
<data-model>
    <!-- Do not remove this - it is used to store information about your app's users: -->
    <model name="user" label="User">
        <field name="name" label="Name" type="text:name"/>

        <display>{name}</display>
    </model>

    <!-- Used for Push Notifications - to send a push notification, create a 'push_notification' object -->
    <!--                               and specify the recipient in the 'belongs to user' relationship -->
    <!-- For more details, refer to: http://resources.journeyapps.com/v4/push-notifications -->
    <model name="push_notification" label="Push Notification">
        <field name="message" label="Message" type="text" />
        <field name="received_at" label="Received At" type="datetime" />
        <field name="created_at" label="Created At" type="datetime" />

        <belongs-to model="user" />
        <display>{message} ({user})</display>
        <notify-user message="{message}" received-field="received_at" recipient-field="user"/>
    </model>

    <!-- ADD MODELS HERE: -->
    <model name="item" label="Item">
        <field name="comments" label="Comments" type="text" />
        <field name="photo" label="Photo" type="photo" />
        <field name="status" label="Status" type="single-choice">
            <option key="Open">Open</option>
            <option key="Closed">Closed</option>
        </field>
        
        <display>{status} - {comments}</display>
    </model>    

</data-model>

For details, see .

We mentioned that we'll use a real-world example of an app throughout the tutorial, and you saw in the page that the Data Model is the best place to start when you build an app on JourneyApps. So let's introduce our real-world example app and then build the Data Model for it:

Navigate to the OXIDE Dashboard (top left corner) and repeat the instructions in to create a new app named "Punch List", and then link your mobile device to that app using the Test App action.

To add our last field for the "status" of our punch list item, we'll use the single-choice type — which is used to create a fixed "list" of values that a specific field can contain). (A full guide to all the possible field types in JourneyApps can be found .) Type single-choice on the next line and insert the auto-complete suggestion for the single-choice field, not the single-choice-integer field, and fill in status for the name and Status for the label. To populate and specify the list of options that this field can contain you need to list <option> tags inside the single-choice field. Therefore, set the contents of those tags to Open and Closed.

You can learn more about xml format strings / string interpolation in detail in of the reference documentation.

🚀
Data Model Configuration
Section 2: Creating a New App
here
this section
JourneyApps Approach to Building Apps section on the What is JourneyApps?