Persist data to Local Storage (or Filesystem)

Description

Should the data in the List be saved in Local Storage or File System on the device? This option is typically only checked if you are building a mobile application that can work when you are disconnected from the internet.

When you build an application for disconnected operation you need to be sure that the data in the application is persisted to Local Storage or the File System to ensure edits are not lost when an application restarts or closes before the user has a chance to synchronize the data back to the server.

Persist data to Local Storage in List Builder
When checked

In order to restore List data from Local Storage you Must also check the 'Restore data in List controls from Local Storage' property in the 'Local Storage' section on the 'Properties' pane of the UX Builder. For a video guide on how this property can be used, watch this video.

The Local Storage section on the UX Properties page

 Using the File System to Persist List data

When you build a mobile app that is intended to operate offline, the typical pattern is to use List controls with Detail Views and to turn on the option to persist the List data to storage.

In web applications, data in the List can be persisted to the browser's localStorage, which is limited to about 5mb of data.

In mobile applications built with PhoneGap, data can be persisted to either Local Storage or the File System. Persisting data to the File System allows you to work with more than 5MB of data in mobile applications when the device is offline.

To turn on the feature to persist List data to the file system, set the Persist where property to FileSystem.

When you set the Persist where option to FileSystem, the Persist mode option is automatically set to Edits and the property is hidden.

If you set Persist where to LocalStorage, you can set the Persist mode to either 'Full', or 'Edits'.

In 'Full' mode, each time the data in the List are edited, the entire List is persisted to localStorage (this is the mode that is implicitly used in all versions of Alpha Anywhere prior to this version).

In 'Edits' mode, each time the data in the List are edited, only the edited rows are persisted to storage.

  •  How Persisting Data to the File System Works

    When you persist List data to localStorage, when the List is initially populated the List data is persisted to localStorage. Each time the List data are edited, the entire List is persisted again to localStorage (unless you change the Persist mode option to Edits). Because writing to localStorage is so fast, and because there is a built-in limit (of approximately 5mb) to the amount of data that must be written to localStorage on each edit, there is no perceptible delay when you are editing the data in the List.

    However, writing to the File System is much slower than writing to localStorage and because there is no longer a built-in limit as to the amount of data in the List, a different approach is taken when the FileSystem option is used. When the List is initially populated, all of the data in the List are written to a file in the File System. Each time the List is edited, the only the rows in the List that have been edited are written to a second file in the FileS ystem. This will file will typically be substantially smaller than the first file (that contains all of the List data), and since the file is likely very small, writing this file to the File System will be very fast, and again, there will be no perceptible delay when you are editing data in the List.

    When the List is synchronized data in the synced rows are written to a third file in the File System and the primary keys of any deleted rows are written to a fourth file in the File System.

    The filenames of these four files in the File System are:

    <namespace>.LIST.<listName>
    The file that contains all of the List data. This file is only written to when the List is initially populated or refreshed. This file can be quite large (several megabytes) - much larger than would be allowed in localStorage.
    <namespace>.LISTEDITS.<listName>
    The file that contains the rows in the List that have been edited, but not yet synced. This file is updated each time the user makes an edit to the List data. This file is typically quite small.
    <namespace>.LISTSYNCEDEDITS.<listName>
    The file that contains the rows in the List that have been edited and synced. This file is updated after the user had synced the List data. This file is typically quite small.
    <namespace>.LISTSYNCEDDELETES.<listName>
    The file that contains the primary keys of the rows in the List that have been deleted. This file is updated after the user had synced the List data. This file is typically quite small.
  • Where:

    <listName>
    The Id of the List.
    <namespace>
    The value of the Namespace property (see image below).
    If the List data are being persisted to localStorage, the Namespace property is used in constructing the localStorage key name. If the List data are being persisted to the File System , the Namespace property is used in constructing the filenames for the four files used to persist the List data and edits.
  •  Location of the List Data Files in the File System

    The files for the List data are stored in the device's 'saved' file system. The location of the device's 'saved' file system is returned by the {dialog.object}.phoneGapGetLocalDirURL('saved') method. The files are stored in a directory (called _offline by default) in this location.

    The following methods can be use to get the file system URL and folder for the List data files:

    {dialog.object}._persistFS()
    The file system URL of the directory in which the List data sub-directory is located
    {dialog.object}._persistFolder()
    The sub-folder in which the files are actually stored - name has a trailing / character.
  • The actual folder name of the files is therefore:

    {dialog.object}._persistFS() + {dialog.object}._persistFolder()
  • For example, the fully qualified name of the file that contains all of the data in the List when the list is initially populated is therefore (assuming the List id is LIST1 and the UX Local Storage Namespace property was set to NS1):

    {dialog.object}._persistFS() + {dialog.object}._persistFolder() + 'NS1.LIST.LIST1'
    In the case where the component is running in AlphaLaunch, the base folder for the files is in a special folder returned by the A5.shell.getAppFileStorageDir() method. The {dialog.object}._persistFS() will return the appropriate base folder name when the component is running in AlphaLaunch.
  •  List Virtualization

    If you are populating a List with a large amount of data, it is strongly recommended that you turn on the List's virtualization feature. With virtualization turned on, populating a List with a large amount of data is substantially faster than populating the List with virtualization turned off.

    To turn on List virtualization, set the Virtualization type property to Dynamic as shown in the image below.

If you select the FileSystem option and your component is not running in PhoneGap, Alpha Anywhere will automatically set the option back to LocalStorage.

 Persisting Data to Local Storage

  •  Defining a UX List Control that can use 'Persist Data to Local Storage (or Filesystem)'

    In order to use this property it is necessary to first create the updatable list control to which it can be applied.

    1. Open the UX Builder. On the UX Controls page view the Data Controls menu and click the [Textbox] option to add a textbox control to the component. Give the control the name 'search'.

    2. Create five additional text box controls on the component. Give these the names city, contact, address, country, and company. Your control pageshould look something like this:

    3. In the Data Controls menu and double click the [List] option to add a list control to the component.

    4. Highlight the list control. In the control's properties list on the right find the List Properties. Click the button next to the 'List properties' property to open the list builder.

    5. Open the 'Data Source' pane of the list builder. In the Data Source Type menu select SQL

    6. Under SQL Data Source, set the Connection string property to the Northwind database. Set the Table name property to the Customers table. After doing this click the button next to the "Field list" property and select the ContactName, CompanyName, City, Country, and Address fields.

    7. In the Return Value section of the Data Source page, set the Return value type to 'PrimaryKey'.

    8. Open the List Layout pane. Use the blue > arrow to move the fields that you just added from the 'Available fields' list to the 'Columns in list'

    9. Open the Properties pane. Place a check next to both the 'Has Detail View' property and the 'Has Search Part' property.

    10. Open the 'Detail View' pane. Under Detail View Properties make sure the Detail view type is set to FieldMap, then click the button next to the Detail view field map property.

    11. In the Define Field Map dialog click on each field and then click on the 'Map Field'' button. Select the textbox control name that corresponds to the field name and click OK. Repeat this process for all five fields.

      The Auto-map Fields button will speed this process up
    12. Now click the Detail View - Quick Setup Genie button at the bottom of the Detail View Pane.

    13. Check "Add buttons to the List Detail View to perform actions such as 'Save edits', Synchronize data', 'etc.'". Then check the 'Create buttons for most commonly used actions' option. Click OK.

    14. Add the button controls to the end of the component.

    15. Click OK to get back to the List Builder.

    16. Open the Search Part. Under Search Part Style click the dropdown control next to the Search Part style property. Choose the 'SingleKeywordControl' option.

    17. Click the button next to the 'Keyword search fields' property. Check all five fields and click OK

    18. Set the Keyword search control to be the 'search' textbox defined earlier.

    19. On the Controls page go to the 'Defined Controls' and click the List-Search Part-Buttons option. To add this button to the component

    20. The 'Select Buttons for the List's Search Part' will appear. Highlight the list control in the top menu and then check the 'Submit Search' option.

    21. Move all of the controls into the following arrangement using the up and down blue arrows in the Controls page. You might need to add a container and turn off some toggles to make everything look alright in Working Preview.

    22. Run in Working Preview.

    23. Now click on one of the records. You should see the fields appear in the Detail View you defined. Make a change to one of the records and click the component's Save' button.

    24. Close working preview by opening the 'Design pane'. Then re-open it. The changes you made should not appear in the updated record.

  •  Using 'Persist Data to Local Storage (or Filesystem)'

    1. Highlight the list control and reopen the List Builder from the List properties property.

    2. Go to the List Builder's 'List Properties' pane. Check the Persist data to Local Storage (or Filesystem) checkbox. Click OK to close the List Builder.

    3. Open the UX Properties page. Scroll down to the Local Storage Properties. Change the 'Namespace' property to be 'DEMO1

    4. Check the 'Restore data in List controls from Local Storage property.

    5. Run in Working Preview. Make some changes to a file and click the Save button in the component.

    6. This time when you go to the design tab and then re-open the Working Preview page you should see your changes are still there.

 Deleting Storage

Deleting the files that contain the List data can be useful when debugging an application. You can delete the files that contain the List data using this Javascript:

var ls = {dialog.object}._localStorageSettings;
{dialog.object}._persistToLocalStorageInitializeKeys(ls,'listId',true);