Appfarm Documentation
Getting startedDocumentationCommunityAppfarm Create
  • Overview
  • Getting Started
    • What is Appfarm?
    • Key concepts
    • Quickstart
      • Speed intro
      • Step-by-step guide
    • Appfarm Showroom
    • FAQ
  • Appcademy
    • Learning paths
    • Appfarm Fundamentals
      • Intro Course
        • 1. Intro to No-Code and Appfarm
        • 2. Navigation in Appfarm Create
        • 3. What is Apps?
        • 4. Intro to UI Editor
        • 5. Data Model
        • 6. App Data
        • 7. Actions
        • 8. Tips and Tricks
        • 9. Intro to practical walkthrough
        • 10. Create a details view of a Project
        • 11. Create a Custom List
        • 12. Swipe and Delete
        • 13. Functionality for simple Create of Data
        • 14. Upload and Download Photos
        • 15. Input Dialog with Validation and Save
        • 16. Dashboard
        • 17. Summary
        • Quiz
      • User Interface Fundamentals
        • Container - Sectioning, Styling and Repeating
        • Conditional Styles
        • Motions
        • Responsive Design
        • Step-by-step workflow
        • Featured UI Components
        • Quiz
      • App Data Fundamentals
        • Data Source Filtering
        • App Variables and Runtime Properties
        • URL Parameters
        • Quiz
      • Actions & Logic Fundamentals
        • Event Handlers
        • Featured Action Nodes
        • Context Parameters
        • Quiz
      • Services Fundamentals
        • Introduction to Services
        • Setting up a Service
        • Scheduling a Service
      • Integration Fundamentals
        • The web request action node
        • Fetch data from an endpoint
        • Map data to a data source
        • Modify the response
        • Nested data mapping
        • Path parameters
        • Authentication
        • Send data to an endpoint
        • Quiz
      • User handling and permissions
        • Users and roles
        • Permissions
        • Creating users
        • Extending the User object class
        • Updating and deleting users
        • Unauthenticated access
        • Quiz
    • Appfarm Professional
      • User Interfaces
        • Featured UI Components
        • Concepts and Use Cases
      • Data Structures & Data Handling
        • Data Features
        • Search & Filters
        • Featured Action Nodes
        • GraphQL
      • Logic & Flow
        • Logical Concepts
        • Date and Time Handling
        • Featured Action Nodes
        • Exception Handling
      • Login & Configuration
        • Login and Authentication
        • Settings, Configuration and Languages
      • Security & Operations
        • Security and Permissions
        • Deployment
        • Schedules and Logs
        • Debugging and App Health
      • Performance & Optimization
        • Optimizing Performance
        • Enhancing Functionality
    • Appfarm Sales Representative
    • Appfarm Developer Forum
      • Session 1: Data Modeling in Appfarm Create
      • Session 2: App Data in Appfarm Create
      • Session 3: Services in Appfarm Create
      • Session 4: Optimizing Performance
    • Background
      • Databases
        • Data modeling 101
        • Database normalization
  • Library
    • UI components
      • Advanced bar chart
      • Advanced bubble chart
      • Advanced combined chart
      • Advanced gantt chart
      • Advanced heatmap chart
      • Advanced line/area chart
      • Advanced pie chart
      • Advanced scatter plot chart
      • Advanced solid gauge chart
      • Animated component
      • Avatar
      • Avatar group
      • Basic bar chart
      • Basic gauge chart
      • Basic line chart
      • Basic pie chart
      • Bottom navigation
      • Button
      • Checkbox
      • Chip group
      • Circular progress
      • Coded component
      • Container
      • Date & time picker
      • Drawable canvas
      • Floating action button
      • Icon
      • Icon button
      • Iframe
      • Image
      • Linear progress
      • List
      • Map
      • Menu list
      • Multi select
      • PDF reader
      • Popover
      • Radio buttons
      • Rich text editor
      • Rich text
      • Select
      • Slider
      • Speed dial
      • Switch
      • Table
      • Tabs
      • Text
      • Text edit
      • View container
      • Visibility group
    • Action nodes
      • Aggregate data
      • Advanced search
      • Auth operations
      • Block
      • Catch exception
      • Copy to clipboard
      • Create file archive
      • Create file object
      • Create object
      • Create user account
      • Delete objects
      • Delete user account
      • Duplicate objects
      • End execution
      • Exit block
      • Exit loop
      • Export data
      • Foreach
      • Generate document
      • If
      • Import data
      • Invalidate cache
      • Log in
      • Log to console
      • Log out
      • Next iteration
      • Navigate
      • Open/close popover
      • Open confirm dialog
      • Open print dialog
      • Open snackbar
      • Open Unsplash dialog
      • Open URL
      • Persist objects
      • Push notifications
      • Read objects
      • Request permissions
      • Run code
      • Run other action
      • Run service
      • Scan barcode/QR code
      • Send email
      • Send SMS
      • Set client language
      • Set data source attributes
      • Set selection
      • Set theme
      • Set user account image
      • Show install app prompt
      • Sleep
      • Sort objects
      • Throw exception
      • Toggle drawer
      • Update object
      • Update secret
      • Update user account
      • Web request
      • While
  • Reference
    • Appfarm Create
      • Appfarm Commander
      • Blue dots
      • Copy & Paste
      • Farmer's Market
      • Find references
      • Find usage
      • Keyboard shortcuts
      • Undo/Redo
      • User preferences
    • Platform concepts
      • Conditions
      • Data bindings
      • Date and time
      • Event handlers
      • Filters
      • Functions
      • Markdown
      • Objects
      • Operators
      • Value processor
    • Dashboard
    • Apps
      • UI
        • Views
          • Dialog
          • Drawer
        • Layout designer
        • Component properties
        • Shareable UI components
      • Data
        • App variables
        • Data sources
        • Calendar data sources
      • Actions
      • App settings
      • App size
      • App health
    • Services
      • Service Endpoints
      • Service settings
      • Service health
      • API explorer
    • Data model
      • Object classes
      • Object class properties
      • Enumerated types
      • GraphQL
        • Queries
        • Mutations
      • Data Extract API
      • Time series data
    • Operations
      • Deploy
      • Schedules
      • Logs
    • Resources
      • Themes
      • Files
      • Fonts
      • Internationalization
    • Configuration
      • Environments
      • Login
        • Custom auth providers
    • Security
      • Users
      • Service accounts
      • Roles
      • Secrets
      • Permissions
        • Conditional Permissions
    • Appfarm Client
      • Developer tools for Apps
      • Developer tools for Services
      • Warnings and errors
  • How to
    • Data modeling
      • Many-to-many relationships
      • Use naming conventions
      • Offline data handling
      • Data silos and White labelling
    • User interface
      • Manage a many-to-many relationship with a Chip group
      • Configure drag and drop
      • Build a drag-and-drop calendar
      • Design a responsive layout
      • Work with flexbox
      • Use Mapbox as a map layer
      • Understand charts
    • Logic and flow
      • Event Log Design
      • Configure advanced search
    • Themes and styling
      • Change the active theme
      • Add custom email templates
    • Enhance your app
      • Add deep links
      • Add keyboard shortcuts
      • Add link previews for social media
      • Apply SEO best practices
      • Change the active language
      • Generate a PDF from a Container
    • Integrations
      • Integrate with external systems
      • Integrate with OpenAI
      • Integrate with Google Analytics (GA4)
      • Configure a custom email account
      • Integrate with a payment provider
      • Integrate with Signicat
      • Integrate directly with an external database
      • Retrieve a Bearer token from Google Cloud
      • Fetch data from BigQuery
      • Retrieve access token from Microsoft Entra ID
    • Workflow automation
      • Update an OAuth 2.0 access token from a service
    • Authentication and access control
      • Add users and assign roles
      • Configure unauthenticated access
      • Implement third-party authentication
    • Security, testing and deployment
      • Add a custom domain
      • Install an app on a device
      • Get ready for Production
      • Optimize performance
      • Security checklist
      • Test and debug
    • Example apps
      • Create an Instagram clone
        • The end result
        • Designing the feed
        • Create new post
        • Add a like-button
        • Add comment-functionality
  • Solution administration
    • Subscription and billing
    • Dedicated tier benefits
    • Guide to GDPR
      • Key principles
      • How Appfarm protects personal data
      • How you can protect your clients’ data
      • Glossary
    • Appfarm and the EU AI Act
  • Policies
    • Appfarm Policies
    • Data Processors
    • Privacy Policy
Powered by GitBook
On this page
  • Designing for offline support - rules, settings and principles
  • The Rules & Settings
  • Principles
  • Testing and debugging
  • Offline App - Walkthrough of Showroom Example

Was this helpful?

Export as PDF
  1. How to
  2. Data modeling

Offline data handling

PreviousUse naming conventionsNextData silos and White labelling

Last updated 11 months ago

Was this helpful?

Appfarm supports creating Apps that may operate in offline environments. Offline support may be necessary in Apps for mobile workforces operating in environments without internet connection, such as in tunnels, on the sea, or inside large buildings without internet. With an offline App, all data in App Variables and Data Sources are cached on the device. When the App goes online, a separate event handler (configured in App Settings) exists for handling the CRUD (Create/Read/Update/Delete) operations toward the database.

However, if you want an App to support both online and offline handling of data, the App needs to be designed for offline support. To change an existing App towards offline data handling is not recommended, as you may learn from this guide.

This guide will provide 2 things: A checklist/overview of the principles, settings in Appfarm Create, and patterns you must follow when designing an App with offline support, and a walkthrough of our Showroom Example where we have a working offline App set up, following our own design patterns.

A full example setup of an Offline App is available in our ! You may try the App yourself, as well as access the setup in Appfarm Create. However, we recommend following the walkthrough below before diving into the setup in Appfarm Create. If you do not have access to Showroom, you may register .

Designing for offline support - rules, settings and principles

The Rules & Settings

  • Database Connected Data Sources should be avoided, only use (or Data Connector). This is recommended for full control of CRUD operations.

  • If you use Deep Data Bindings (Example: displaying Orders.Product.Price), you must use (Example: You must add Products as a Reference Data Source on the Orders Data Source)

  • Do not use the On App Load or On App Loaded event handlers for data handling (try to avoid them, as the On Online event handler will always execute when refreshing or accessing your App in online mode).

  • Use the event handler for both saving unsaved data (persisting new/update objects, or deleting objects) and reading data.

  • All Actions that are intended to save data (persist objects) should handle both Offline and Online state. Example: Save Product should have one IF block for offline (based on the App Variable Is Online) where data is read into a Data Source holding all data and being the "offline master data source" for that object type. In addition, there should be one IF block for online mode, where the Product is saved (persist objects) in addition to being added to that same master data source

  • The App must have the flag ticked. This is in fact the only required setting.

  • If offline opening of documents is required, those document URLs must have been opened at least once before the App goes offline. You need to make sure the files are cached while online first, before using Open URL on these documents while offline. You may run this code snippet from the App (while online) to force caching of all file data.

    // myFiles must be added as a data source parameter
    Promise.all(myFiles.map(item => {
        return fetch(item.__fileContentLink)
    }))
        .then(resolve)
        .catch(reject)

Principles

We recommend having as few Data Sources as possible, and all Data Sources should be Runtime Only. In other words, do not have multiple Data Sources of the same type for holding objects - the only case where this should be the case is for the single-cardinality Data Sources used for Creating or Updating single objects

You may add a multi-cardinality Runtime Only Data Source Products (master) used for holding all Products, and another single-cardinality Data Source Product (new/edit) used for editing or creating a new Product.

Read all updated or created objects into a multi-cardinality Runtime Only Data Source. When objects are updated or created, all data sources holding the same objects must be manually refreshed. This is automatically done when using Database Connected Data Source upon persisted changes, but in offline Apps, we do not have that luxury.

When you want to create a new Product, you may do it in the Product (new/edit) data source. But the Save button should read the created object into Products (master). If the App is Online, the Product (new/edit) should also be Persisted.

All Actions performing updates to data should Persist when Online. The Action should have explicit logic handling the Online state and the Offline state.

Example:

Deleted objects should be marked as deleted, not actually deleted, while offline. You need to know the ID of the object to be deleted. Therefore, you should add a Runtime Only property Marked for delete or similar to the Data Source, and set this flag to true when an object is deleted. All UI and logic should exclude the objects with Marked for delete = true.

The Dialog for editing a Product may have a Delete button. But instead of actually deleting the object, you may perform an Update Object of that object in the Products (master) Data Source, setting the flag Marked for delete to true.

Use the On Online Event Handler for Persisting unsaved data and Deleting objects to be deleted. The Action should start with persisting new objects, then persisting updated objects (in iterations, with catch exception), and then delete objects marked for delete (in batch, or in iterations, depending on the requirements for exception handling) with exception handling.

Then the Action should read all data from the database.

The On Online Event Handler runs on every refresh of the App when it is online. So, if the App is always online, nothing will ever be persisted or deleted in the first part of this action, but data will always be read in the second part. If the App has been offline and goes online, this Action is triggered, and data is both saved/deleted and then refreshed from the database.

Make the user aware of the offline state in the App, and disable unnecessary functionality. You should display some information to the user when the App is in offline mode. Some functionality may be considered "unnecessary" to have in the short timespans the App is offline. Offline functionality comes with complexity (=cost), so you might just want to hide or display certain buttons.

Example:

Testing and debugging

Start by testing everything in online mode as normal. The Enable Offline flag in the App Settings is the "trigger" that changes how this App behaves at runtime. Make sure this flag is enabled while testing.

You may simulate Offline Mode in your browser from the Developer Console -> Networks tab.

The first thing you may encounter is that loading data fails because Reference Data Source has not been set. When deep data bindings are used, Appfarm generates some GENERATED data sources (for the joins towards the connected object classes). Your Offline App should not have any Generated Data Sources. You may toggle the display of these Data Sources in the Dev Tool if you open the Console in the browser and type the following: appfarmDebug.toggleGeneratedDataInDevTools()

Offline App - Walkthrough of Showroom Example

About the App

The App allows the user to see all Products and filter Products by Category. The user may add new Products (and upload a Product Image), edit Products and delete Products.

The App operates as normal if the user is online. When the App goes offline, the user is visually notified, and all data added, updated, or deleted are stored on the device. The user may safely refresh the App while offline. When the App goes online, the new and updated Products are saved to the database (persisted), and the deleted Products are deleted from the database.

App Data

All Data Sources are Runtime Only, except the Data Connector Data Source.

  • Products (data connector for delete): Only used for deleting products once the App goes online and Products have been Marked for delete while offline.

  • Products (master): Holds all products, including all new, updated, and deleted products while offline.

  • Product Images (master): Holds all Product Images, and is used as a Reference Data Source for Products (master). It also holds all new Product Images added to existing or new Products.

  • Product (new/edit): Used in the Dialog for adding new Products or editing existing Products. For creating new Products, we create a new object into this Data Source, and upon save - read this object into the Products (master) Data Source. For editing Products, we read the object to be edited from the Products (master) Data Source into this Product (new/edit) Data Source, and back again upon save.

  • Product Image (new/edit): For saving a new Product Image to be linked to the new or existing Product. New Product Images are read into the Product Images (master) upon save.

  • App Variables.Offline edit done: We set this boolean variable to true every time we create, update or delete data while offline. This is not required, but we do it for having a condition in the On Online Action, in order to skip the whole block of persist/delete logic if no changes have been done.

Actions and UI

  • Save Product: Logic for both Online and Offline mode. Both of them read the updated or created Product and Image back into the master data sources, and close the dialog. But if the App is online, we also persist the changes to the database.

  • Delete Product: If the App is offline, we mark the Product "Marked for delete" and close the dialog. Note that the list of Products in the UI filters out the Products Marked for delete, so these Products appear to be deleted to the user. If the App is online, we delete the Product directly towards the database (using the Data Connector Data Source), and we also remove it from the Products (master). Remember, Runtime Only Data Sources need to be manually refreshed, so a deleted object in one data source does not reflect automatically on other data sources holding that same object.

  • On Online (event handler): The Action starts with a block for persisting new Products, persisting changes to updated Products, and deleting Products Marked for delete. Note that we use the built-in Object Class Property Object State for differentiating between new and updated products!

And finally: The Enable Offline flag is ticked in the App Settings.

Use a Data Source for deleting objects once online. When the App goes online, you may perform a Delete Objects towards that Data Connector Data Source, deleting the objects Marked for delete.

We have created an example app in our . You may test the App here, and you may locate the App inside Appfarm Create (if you have for Showroom) by selecting the solution Appfarm Showroom in the top left menu.

Showroom
signed up
Showroom
here
Runtime Only Data Sources
On Online
Enable Offline
Example warning when an App is Offline
Reference Data Sources
Data Connector