05-06-2022 12:23 - edited 05-06-2022 12:23
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

05-06-2022 12:23 - edited 05-06-2022 12:23
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi all,
I want to handle settings updates through files not sockets because it's not stable.
I saved the settings in a separate file and used a separate file called common/device-file-settings.js to handle the new received settings file.
I am receiving a strange "TypeError: Expected a function." on line 39, an exception printed on line 45.
I am passing the fs from app/index.js together with the settings callback function in order to use it here.

05-06-2022 13:35
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


05-06-2022 13:35
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
Are you sure you imported fileSystem and not fs?
Gondwana Software
05-06-2022 13:41 - edited 05-06-2022 13:42
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

05-06-2022 13:41 - edited 05-06-2022 13:42
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi @Gondwana,
Yes, this is the code:
app/index.js
import * as fs from "fs";
...
deviceFileSettings.initialize(settingsCallback, fs);
common/device-file-settings.js
import { inbox } from "file-transfer";
export const SETTINGS_FILE_NAME = "settings";
export const SETTINGS_TYPE = "cbor";
export const SETTINGS_FILE = "settings.cbor";
let settings, onsettingschange, fileSystem;
export function initialize(callback, fs) {
fileSystem = fs;
onsettingschange = callback;
inbox.addEventListener("newfile", processAllFiles);
}
...
function loadSettings(fileName) {
try {
var filePath = `/private/data/${fileName}`;
if (fileSystem.existsSync(filePath)) {
return fileSystem.readFileSync(filePath, SETTINGS_TYPE);
} else {
return fileSystem.readFileSync(`/private/data/`+SETTINGS_FILE, SETTINGS_TYPE);
}
} catch (ex) {
console.log(ex);
// return {};
}
}

05-06-2022 13:54
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


05-06-2022 13:54
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
Without digging into it too much, I'm now wondering whether the use of the 'common' directory might be problematic. I think 'common' is for code that is to be imported into both the device (watch) and companion (phone). However, the fs API is only relevant to the device. I could be totally wrong that this is the issue, but maybe try moving device-file-settings.js out of common.
Also try using console.log to see if/when fileSystem is being initialised, and whether it has been defined when being used in loadSettings.
Gondwana Software
05-06-2022 14:06
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

05-06-2022 14:06
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi @Gondwana,
Thank you for the detailed description.
Pretty valid point, but I tried that already and no success.
I will dig more to see why the fs is not behaving as it should.
Will share whatever I found.
Cheers 🍻

05-06-2022 14:11
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


05-06-2022 14:11
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
If you put device-file-settings.js in the app folder, it should be able to import fs directly. That would simplify things. Simple is good.
Gondwana Software

05-06-2022 14:29
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

05-06-2022 14:29
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
I've moved it directly to the app folder, and when I try to import the fs, a build cannot be created:
"TypeError: Cannot create property 'code' on boolean 'true'"
I am missing some important points.
05-06-2022 15:08
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


05-06-2022 15:08
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
That's probably something simple, like a typo. If you're using .code in your source, backtrack from there. It sounds like .code is being applied to a simple variable or function return value, rather than an object.
I think you've already discovered the ossapps repo. There's bound to be several things in there that use file transfer (eg, BIG TIME). You could refer to code from there. (Beware of simply pasting: that can create more problems than it solves.)
Gondwana Software

05-09-2022 17:13
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

05-09-2022 17:13
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi @Gondwana,
Thank you for the thoughts, ideas and suggestions, but it's not a typo.
The setting file names I am transferring are with "_" and I am not keeping them like "settings.color.cbor", but "settings_color.cbor".
The issue is the file system import.
I tried everything, I was moving the "device-file-settings.js" file in different directories without success:
- app directory
- Error: "Unhandled exception: TypeError: Cannot read property 'readFileSync' of undefined"
- "custom" directory
- Error: Unhandled exception: TypeError: Expected a function.
I am posting here the directory structure and also the code of the files:
app/index.js
import clock from "clock";
import document from "document";
import * as util from "../common/utils";
import { me as appbit } from "appbit";
import { today } from 'user-activity';
import { HeartRateSensor } from "heart-rate";
import * as deviceSettings from "../common/device-settings.js";
import * as deviceFileSettings from "./custom/device-file-settings.js";
import * as myClock from "./custom/clock.js";
import * as myHRM from "./custom/hrm.js";
import * as myActivity from "./custom/activity.js";
import * as fsys from "fs";
.....
deviceFileSettings.initialize(settingsCallback, fsys);
app/custom/device-file-settings.js
import { inbox } from "file-transfer";
export const SETTINGS_FILE_NAME = "settings";
export const SETTINGS_TYPE = "cbor";
export const SETTINGS_FILE = "settings.cbor";
let settings, onsettingschange, fs;
export function initialize(callback, fileSys) {
fs = fileSys;
onsettingschange = callback;
inbox.addEventListener("newfile", processAllFiles);
}
function processAllFiles() {
let fileName;
while (fileName = inbox.nextFile()) {
processSettingFile(fileName);
}
}
function processSettingFile(fileName) {
settings = loadSettings(fileName);
onsettingschange(settings);
fs.unlinkSync(fileName);
}
// Load settings from filesystem
function loadSettings(fileName) {
try {
var filePath = `/private/data/${fileName}`;
return fs.readFileSync(filePath, SETTINGS_TYPE);
} catch (ex) {
console.log(ex);
return fs.readFileSync(filePath, SETTINGS_TYPE);
// return {};
}
}
everytime it fails on this line:
"return fs.readFileSync(filePath, SETTINGS_TYPE);"
There is some dependency on the import so the fs cannot be recognized.

05-09-2022 18:53
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


05-09-2022 18:53
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Why don't you just
import * as fsys from "fs";
in device-file-settings.js? Try to simplify things and eliminate fs and fileSys.
At very least, console.log(fs) in loadSettings to see whether it's actually defined.
Gondwana Software

05-10-2022 02:31
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

05-10-2022 02:31
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi @Gondwana,
Thank you for your prompt reply.
The build is failing if I use the imported fs, I tried that already.
Here is the code:
import { inbox } from "file-transfer";
import * as fsys from "fs";
export const SETTINGS_FILE_NAME = "settings";
export const SETTINGS_TYPE = "cbor";
export const SETTINGS_FILE = "settings.cbor";
let settings, onsettingschange, fs;
export function initialize(callback) {
// fs = fileSys;
onsettingschange = callback;
inbox.addEventListener("newfile", processAllFiles);
}
...
// Load settings from filesystem
function loadSettings(fileName) {
try {
// console.log(fsys);
var filePath = `/private/data/${fileName}`;
return fsys.readFileSync(filePath, SETTINGS_TYPE);
} catch (ex) {
// console.log(ex);
// return fsys.readFileSync(filePath, SETTINGS_TYPE);
// return {};
}
}
The error:

05-10-2022 02:43
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


05-10-2022 02:43
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Unless I'm misinterpreting, that error message is referring to companion code. fs doesn't exist in the Companion API. You can only access the fs on the device (watch). Don't try to use fs in companion or common directories.
Gondwana Software

05-10-2022 03:07 - edited 05-10-2022 03:31
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

05-10-2022 03:07 - edited 05-10-2022 03:31
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi @Gondwana,
I think what is presented in the log is just the app flow through the watch files:
- app/index.js
- companion/companion-settings.js
- app/device-file-sharing.js
I do not have any import of the fs into the companion, but only import { outbox } from "file-transfer";

05-10-2022 13:43
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


05-10-2022 13:43
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
I just tried to duplicate getting a build error reported after "Building companion". The ony way I could do it is if there was a build error in the code that was being built for the companion (ie, /companion/... or /common/...). Build errors in device-only (ie, watch-only) code were always emitted prior to "Building companion".
Gondwana Software
05-11-2022 05:44
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

05-11-2022 05:44
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
Hi @Gondwana,
I agree, but the behaviour is weird because I am not changing anything in companion components when I edit in the device-file-settings.js and when I import fs into it, the build fails.

05-11-2022 13:47
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post


05-11-2022 13:47
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
PM sent.
Gondwana Software

05-17-2022 11:34
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post

05-17-2022 11:34
- Mark as New
- Bookmark
- Subscribe
- Permalink
- Report this post
- Who Voted for this post?
I found the reason why the build is failing.
The fs was loaded in the companion/index.js and I missed it because I was assuming only the import is there:
import * as mySettings from "./custom/companion-settings";
mySettings.initialize();
I was having the file like this :
import * as mySettings from "./custom/companion-settings";
import * as fs from "fs";
mySettings.initialize();
This was causing the build to fail because companion cannot import fs.
