07-20-2018 07:22 - edited 07-20-2018 09:39
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

07-20-2018 07:22 - edited 07-20-2018 09:39
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Is there a way to set default values for various components in settings/index.jsx? In other words, instead of the user starting with a settings page that looks like this:
I'd like to start the user with a page that looks something like this:
It seems to me that this should be easy to do, and it probably is. But I'll be danged if I can find a way to do it.
Here is the code in the index.jsx file:
function mySettings(props) { return ( <Page> <Section title={<Text bold align="center">Functionally Fuzzy Settings</Text>}> <Toggle settingsKey="bSteps" label="Steps" /> <Toggle settingsKey="bHRM" label="Heart Rate" /> <Toggle settingsKey="bDigiTime" label="Digital Time" /> <Toggle settingsKey="bAMPM" label="Use AM/PM?" /> <Toggle settingsKey="bBattery" label="Battery" /> <Toggle settingsKey="bDate" label="Date" /> </Section> <Section title={<Text bold align="center">Weather Settings</Text>}> <Select settingsKey="selWeather" label="Weather?" selectViewTitle="None" options={[ {name:"Yahoo Weather"}, {name:"OpenWeather"}, {name:"None"} ]} /> <Toggle settingsKey="bTemp" label="Temperature" /> <TextInput settingsKey="strKey" label="OpenWeather Key" placeholder="Enter OpenWeather Key Here" action="Add/Update Key" //disabled={!(this.props.settings.bTemp === "true")}// && this.props.settings.selWeather.name === "OpenWeather"} /> <Toggle settingsKey="bImperial" label="Temperature Unit On=F / Off=C" /> </Section> </Page> ); } registerSettingsPage(mySettings
Answered! Go to the Best Answer.

Accepted Solutions
07-20-2018 17:38
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


07-20-2018 17:38
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Unfortunately, I'm between computers ATM, and it seems I've never had to do this with toggles. However, I think you may need to call setItem() passing the setting value as a JSON string. Here's something I cooked earlier that works with lists; you'll have to adapt it to work with toggles, of course...
// Initialise settings to default values: if (locale.language === "en-US") setDefaultSetting("dateFormat", {"selected":[1],"values":[{"name":"Dec 25","value":1}]}); else setDefaultSetting("dateFormat", {"selected":[0],"values":[{"name":"25 Dec","value":0}]}); setDefaultSetting("distMeasure", {"selected":[0],"values":[{"name":"Steps","value":0}]}); setDefaultSetting("activeFrom", {"selected":[6],"values":[{"name":"6 AM","value":6}]}); setDefaultSetting("activeTo", {"selected":[6],"values":[{"name":"6 PM","value":18}]}); function setDefaultSetting(key, value) { let extantValue = settingsStorage.getItem(key); if (extantValue === null) settingsStorage.setItem(key, JSON.stringify(value)); }
Gondwana Software

07-20-2018 13:54
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


07-20-2018 13:54
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
A way to do it is to initialise the settings in companion/index.js.
You can find out what values work by inspecting the values that get stored by the system when the settings UI is used to specify a value.
Gondwana Software

07-20-2018 17:14
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

07-20-2018 17:14
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Yes. And that is exactly what I'm trying to do. What I don't know, however, is the code I need to use to make it happen.
I thought maybe something like settingsStorage.setItem("bSteps") = true; might work, but it gives me a scary error message on build and I think that setItem doesn't even exist. I don't believesettingsStorage.initialize exists either.
I know what values I want to set and I know what I want to set them to. I just need the code to do it.
My code in companion/index.js looks something like this:
import { settingsStorage } from "settings";
let defaultSettings = { bSteps: true, bHRM: false, bDigiTime: false, bAMPM: false, bBattery: true, bDate: false, bTemp: false, bImperial: true, selWeather: 0 }
function sendSettingData(data) {
if (messaging.peerSocket.readyState === messaging.peerSocket.OPEN) {
messaging.peerSocket.send(data);
}
}
// Message socket opens
messaging.peerSocket.onopen = () => {
console.log("Companion Socket Open");
};
// Message socket closes
messaging.peerSocket.onclose = () => {
console.log("Companion Socket Closed");
};
//A user changes settings
settingsStorage.onchange = evt => {
if (evt.oldValue !== evt.newValue) {
let data = {
key: evt.key,
newValue: JSON.parse(evt.newValue)
};
sendVal(data);
}
};
// Listen for the onerror event
messaging.peerSocket.onerror = function(err) {
console.log("Connection error: " + err.code + " - " + err.message);
}

07-20-2018 17:38
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


07-20-2018 17:38
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Unfortunately, I'm between computers ATM, and it seems I've never had to do this with toggles. However, I think you may need to call setItem() passing the setting value as a JSON string. Here's something I cooked earlier that works with lists; you'll have to adapt it to work with toggles, of course...
// Initialise settings to default values: if (locale.language === "en-US") setDefaultSetting("dateFormat", {"selected":[1],"values":[{"name":"Dec 25","value":1}]}); else setDefaultSetting("dateFormat", {"selected":[0],"values":[{"name":"25 Dec","value":0}]}); setDefaultSetting("distMeasure", {"selected":[0],"values":[{"name":"Steps","value":0}]}); setDefaultSetting("activeFrom", {"selected":[6],"values":[{"name":"6 AM","value":6}]}); setDefaultSetting("activeTo", {"selected":[6],"values":[{"name":"6 PM","value":18}]}); function setDefaultSetting(key, value) { let extantValue = settingsStorage.getItem(key); if (extantValue === null) settingsStorage.setItem(key, JSON.stringify(value)); }
Gondwana Software

07-28-2018 19:26 - edited 07-28-2018 19:30
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

07-28-2018 19:26 - edited 07-28-2018 19:30
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
Hi,
Did you ever use setItem to set a colour value?
I want to be able to select one of the colours in the list when the companion app starts.
I am using the code below to try and find what works when, as far as setting values in the settings UI at run-time goes.
// These 2 work
// toggle
settingsStorage.setItem('tglPaintHourNumbers', 'true'); // selectbox
settingsStorage.setItem('selShowAt0', JSON.stringify({ selected: [4] })); // These don't. All the 'clr*' properties are colour-selectors
// I want to select the 3rd option in the selectbox (or colour #FFFFFF) settingsStorage.setItem('clrHourNumbersColour', JSON.stringify({ selected: [3] })); settingsStorage.setItem('clrHourColour', JSON.stringify({ selected: ['#FFFFFF"'] })); settingsStorage.setItem('clrMinColour', JSON.stringify({ color: 3 })); settingsStorage.setItem('clrSecColour', JSON.stringify({ color: '#FFFFFF"' }));
Cheers,
Nick
07-28-2018 19:33
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


07-28-2018 19:33
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I think the best general approach is to do a getItem() and inspect what comes back when the user selects what you want as a default. Pass that same data to setItem() to initialise a default. (It seems that you can leave out some attributes, but I never bothered exploring this.)
Gondwana Software

07-28-2018 19:48
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

07-28-2018 19:48
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Thanks for the quick reply!
I tried the following
let cc = settingsStorage.getItem('clrHourNumbersColour'); console.log(cc) ; // the result was '#FFCCCC'
// so I then did
settingsStorage.setItem('clrHourNumbersColour', '#FFCCCC');
Alas, it caused the following error

07-28-2018 19:53
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


07-28-2018 19:53
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
What type of component are you using in your .jsx? ColorSelect?
Gondwana Software

07-28-2018 19:55 - edited 07-28-2018 19:55
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

07-28-2018 19:55 - edited 07-28-2018 19:55
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
let handColours = [
{color: "#FFCCCC"},
{color: "#FF7F7F"},
{color: "#FF0000"},
{color: "#CC0000"},
{color: "#990000"},
{color: "#00A629"},
-snip-
{color: "#FF009E"},
{color: "#FFF8DC"},
{color: "#A9A9A9"},
{color: "#696969"},
{color: "#DCDCDC"},
{color: "#000000"}
];
...
...
...
<Section title={<Text bold align="center">Hour numbers colour</Text>}> <ColorSelect settingsKey="clrHourNumbersColour" colors={handColours} /> </Section>

07-28-2018 19:59 - edited 07-28-2018 20:01
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

07-28-2018 19:59 - edited 07-28-2018 20:01
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
Found it!
settingsStorage.setItem('clrSecColour', JSON.stringify( '#FFCCCC' ));
instead of
settingsStorage.setItem('clrSecColour', '#FFCCCC' );
So the total info I now have on this is
// toggle
settingsStorage.setItem('tglPaintHourNumbers', 'true');
// selectbox (select 5th entry) settingsStorage.setItem('selShowAt0', JSON.stringify({ selected: [4] })); // colour selector settingsStorage.setItem('clrSecColour', JSON.stringify( '#FFCCCC' ));
07-28-2018 20:01
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


07-28-2018 20:01
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Well done! I was going to guess that, but thought I should test it first. 🙂
Gondwana Software

07-28-2018 20:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

07-28-2018 20:03
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Thanks for helping out!
I hope this will save someone else the trouble of banging his head against the wall.

05-27-2021 10:42
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

05-27-2021 10:42
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Sorry to revive a very old thread, but I'm trying to do something similar and I am having issues.
I tried to use settingsStorage.getItem() and .setItem() inside my companion class, in order to check if a value is set and if it isn't set, set a default. But I keep getting exceptions when I try to access settingsStorage object methods.
Error: ENOENT: no such file or directory, open '/Users/f92a4nu/Library/Application Support/Fitbit OS Simulator/mira/companion/app_dec65d47-e3a2-4e98-8610-7cef3e65bd78/settingsstorage/kanjiColourGradient
When I just try to set the item, this happens when I first install the app, though the default value does seem to be set, and if I run the app again I won't get the same exception for that config. When I try this with multiple configs, it seems I have to run it again for each config to clear them one by one.
If I try to get the item first to check before setting, then the exception prevents the item from being set, so the default settings never work.
I have also tried to write a config file with default settings but that doesn't seem to work when my app loads its settings.
I'm curious where the settingsStorage.setItem() should be called from, since it gives an exception when called from the companion/index.js file.

05-27-2021 13:53
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


05-27-2021 13:53
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
settingsStorage.setItem() etc definitely works in companion/index.js, assuming you've imported settingsStorage.
In some cases, I've found it necessary to set defaults in settings/index.jsx, because sometimes the jsx starts before companion/index.js. It's accessible via the argument passed to settingsComponent().
I note that your error message has incorrect capitalisation of settingsStorage; that may be significant (or not).
Gondwana Software

05-27-2021 14:22
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

05-27-2021 14:22
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
If I uninstall the app from the simulator and then run it again, it gives exceptions initially when I use settingsStorage.setItem() or getItem(). This was on a Mac. I just tried it again on my PC and while I did see the same error yesterday, now it seems to be working. No idea why, won't be surprised if it stops working again later.
For reference, here is my companion/index.js
import { settingsStorage } from "settings";
import * as messaging from "messaging";
if (settingsStorage.getItem('kanjiColourGradient') == null) {
settingsStorage.setItem('kanjiColourGradient', 'true');
}
if (settingsStorage.getItem('clockColor') == null) {
settingsStorage.setItem('clockColor', JSON.stringify('#68FC68'));
}
if (settingsStorage.getItem('stepsColor') == null) {
settingsStorage.setItem('stepsColor', JSON.stringify('#FFFF00'));
}
// Settings have been changed
settingsStorage.onchange = function(evt) {
if (evt.newValue !== evt.oldValue) {
sendValue(evt.key, evt.newValue);
}
}
// Send key/value pair
function sendValue(key, val) {
console.log("send value")
if (!key || !val) {
return;
};
sendSettingData({
key: key,
value: JSON.parse(val)
});
}
// Send JSON object
function sendSettingData(data) {
console.log("send settings data")
if (messaging.peerSocket.readyState === messaging.peerSocket.OPEN) {
messaging.peerSocket.send(data);
} else {
console.log("No peerSocket connection");
}
}
I'm curious how you set default values in the settings/index.jsx. Would "props" in the code below be the argument you are referring to? Could you give an example of how you use it?
function SettingsPage(props) {
return (
<Page>
...
</Page>
);
}
registerSettingsPage(SettingsPage);
05-27-2021 14:34
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

05-27-2021 14:34
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I should clarify what I mean when I say it's working. The companion app seems to show the expected default settings, but the clockface doesn't show the expected colour, it seems setting the default values doesn't make those values get written to a config file. I still have to manually change a setting for it to be rendered in the clock face.

05-27-2021 15:08
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


05-27-2021 15:08
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
props.settingsStorage.getItem(...), etc (of the top of my head).
It's up to you to send settings from companion to watch. It doesn't happen automatically. To avoid latency, I ensure that the watch's initial state (colours, etc) matches the default settings. Duplication. 😞
Gondwana Software
05-27-2021 15:16
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

05-27-2021 15:16
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Thanks, I'll have a look at the settings/index.jsx and see if I can make something work there.
To clarify, when I change a setting manually in the companion settings app, it does get sent to the watch and the UI is updated and config is saved to file and reused later.
But in the companion app when I set a default value, this is reflected in the companion app but not the clockface. I have tried saving config to a file but had problems with imports. Not sure I can write a config file directly in the companion app, and I also thought about manually triggering an onchange event but haven't been able to do that yet either.

05-27-2021 15:25
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


05-27-2021 15:25
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
I think the onchange event only occurs when something changes in the .jsx. If you're changing values in .js code, you'll probably have to explicitly call the send-to-watch code you've written.
Even then, there will be a small delay before the watch receives those initial settings. That's why I'd get the watch to default to those of its own accord. It also spares you from having to do that initial transfer.
Gondwana Software

05-27-2021 15:51
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

05-27-2021 15:51
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
Yeah, I tried calling the sendValue() method after setItem() in the companion app, but never saw any change to the UI, it always just stayed with the default colour, which I had already set manually in the clock face before even trying to set default config values.
My main issue is just getting default values to be shown as selected in the companion app. Especially for toggles, I don't want features that are enabled by default to appear as toggled off in the settings.
Anyway, setting the value in the settings/index.jsx seems to be working well now!
function SettingsPage(props) {
if(props.settingsStorage.getItem("clockColor") == null) {
props.settingsStorage.setItem('clockColor', JSON.stringify('#68FC68'));
}
return (
<Page>
<Section
title={<Text bold align="center">CHANGE CLOCK COLOR</Text>}>
<ColorSelect
settingsKey="clockColor"
colors={colorSet}
/>
</Section>
...
</Page>
);
}
As I was already setting default colour in the clock, this works perfectly, but when testing I did see the delayed update you mentioned, so yeah, worth noting for anyone not already setting a default value in the clock code.
Thanks for helping with this! Much appreciated!
