Adding a Bangle.js App Settings Page

If you've made an app, often you may want to provide some options to allow it to be customised. While you can use E.showMenu to add an options screen inside your app, Bangle.js provides a way to add extra menus to the global Settings application.

First, check out the tutorial on adding an app to the Bangle.js App Loader as it'll help you to understand about metadata.json.

First off, you need to store your settings in a file. Apps in Bangle.js generally use either "myapp.json" or "myapp.settings.json" as the filename, where myapp is your app's ID. We're using "myapp.json" here (which what we would suggest).

Using settings in your app

In the app itself, you can read settings using code like this:

var settings = Object.assign({
  // default values
  something: 123,
  anotherthing: 456,
}, require('Storage').readJSON("myapp.json", true) || {});

If you don't set defaults, your code needs to be able to handle missing items:

// read settings file, or if it doesn't exist use {}
var settings = require('Storage').readJSON("myapp.json", true) || {};

// Use the setting, or a default value if undefined
var value = settings.something!==undefined ? settings.something : 123;

// Or a cleaner version when you know a value of '0' isn't valid:
var value = settings.something || 123;

It's important to think about both memory usage and speed:

var settings = require('Storage').readJSON("myapp.json", true) || {};
var value = settings.something || 123;
delete settings; // remove unneeded settings from memory

Note: You should never depend upon a settings file being present, or even having some field, so defaults are a good idea. Someone may have deleted it or upgraded from an older version of your app.

Testing settings in your app

When you're loading settings inside your app, you can manually write:

require('Storage').writeJSON("myapp.json", {
  something : 123
});

To set up some settings. You can enter this at the console and then reload your app to check then take effect.

It's also important to check your app works with no settings file using require('Storage').erase("myapp.json"). It's very easy to create an app that works for you, submit it to the app store and find nobody else can use it because they don't have a settings file.

The Settings page

Now, develop your setting page. In the Web IDE, upload to RAM and start with the following:

(function(back) {
  var FILE = "myapp.json";
  // Load settings
  var settings = Object.assign({
    something: 123,
  }, require('Storage').readJSON(FILE, true) || {});

  function writeSettings() {
    require('Storage').writeJSON(FILE, settings);
  }

  // Show the menu
  E.showMenu({
    "" : { "title" : "App Name" },
    "< Back" : () => back(),
    'On or off?': {
      value: !!settings.onoroff,  // !! converts undefined to false
      format: v => v?"On":"Off",
      onchange: v => {
        settings.onoroff = v;
        writeSettings();
      }
    },
    'How Many?': {
      value: 0|settings.howmany,  // 0| converts undefined to 0
      min: 0, max: 10,
      onchange: v => {
        settings.howmany = v;
        writeSettings();
      }
    },
  });
})(load)

It's pretty easy to add different options - check out the E.showMenu docs for more ideas.

This is great for testing, however to create a settings app, you must remove the (load) from the end of the code, so it should look like this:

(function(back) {
  var FILE = "myapp.json";
  // Load settings
  var settings = Object.assign({
    something: 123,
  }, require('Storage').readJSON(FILE, true) || {});

  function writeSettings() {
    require('Storage').writeJSON(FILE, settings);
  }

  // Show the menu
  E.showMenu({
    "" : { "title" : "App Name" },
    "< Back" : () => back(),
    'On or off?': {
      value: !!settings.onoroff,  // !! converts undefined to false
      format: v => v?"On":"Off",
      onchange: v => {
        settings.onoroff = v;
        writeSettings();
      }
    },
    'How Many?': {
      value: 0|settings.howmany,  // 0| converts undefined to 0
      min: 0, max: 10,
      onchange: v => {
        settings.howmany = v;
        writeSettings();
      }
    },
  });
})

Save the file to myapp.settings.js on the Bangle's storage. If the app JSON is set up, you should now be able to access the settings by going to Settings -> App/Widget Settings and your App's Name.

Adding to the app loader

Assuming this is your app, add the lines marked:

{
  "id": "myapp",
  "name": "My App",
  "version": "0.01",
  "description": "...",
  "icon": "app.png",
  "tags": "...",
  "supports": ["BANGLEJS","BANGLEJS2"],
  "storage": [
    {"name":"myapp.app.js","url":"app.js"},
    {"name":"myapp.settings.js","url":"settings.js"}, // < ------- HERE
    {"name":"myapp.img","url":"app-icon.js","evaluate":true},
  ],
  "data": [{"name":"myapp.json"}]  // < ------- HERE
}

And you're finished!

Extra 1: Applying widget settings immediately

Sometimes you may want settings for a Widget, and that widget may be running in the background while the settings page is active. In that case we'd suggest:

Extra 2: Loading Settings from your app

Sometimes you may want to enter the settings menu direct from your app. If you do, you can use this code:

eval(require("Storage").read("myapp.settings.js"))(()=>load());

You should replace the call to load() with a function that displays the main menu of your app, or going < Back from settings will go back to the clock.

This page is auto-generated from GitHub. If you see any mistakes or have suggestions, please let us know.