• Hey guys,
    long time lurker, first time poster here.
    So i'm having trouble understanding / fixing this.
    I created my own app.js, got everything to work that this is my default app.
    The app works fine when i launch it from the WebIDE, however, when installing it from the apploader and then "reloading", i suddenly have code duplicated in ram, therefore functions being called twice.
    So e.g.
    in ram it is like this:
    Bangle.on("accel", onAccel);
    Bangle.on("accel", onAccel);

    when launching from the WebIDE, this duplication is not present.
    What am i missing? How do i get a "clean" launch after installing?

    Thanks in advance.

    edit: when installing from the webide after the installation from the apploader the console prints:
    Uncaught Storage Updated!

    might be related?

  • Would you mind sharing your code? It would make it easier to guess what might be wonky 🙂

  • ill post the relevant sections (i guess). This is basically toplevel, everything else is just functions.

        lockTimeout: 0,
        backlightTimeout: 10000,
        btnLoadTimeout: 0,
        hrmSportMode: -1
    var bootTimer = 0;
    setInterval(function() {
        if (BTN.read())
        else bootTimer=0;
        if (bootTimer<10) E.kickWatchdog();
    }, 2000);
    Graphics.prototype.setFontAnton = function(scale) {
        // Actual height 69 (68 - 0)
    onInit(); // set up our new services
    function onInit() {
        NRF.on('connect', function () { connected = true;
        NRF.on('disconnect', function () { connected = false;
        NRF.on('bond', function(status) {
            uiLog("bond: " + status);
            if(status == "success"){
                connected = true;
            } else {
                connected = false;
        NRF.on('advertising', function(isAdvertising) {
            uiLog("advertising: " + isAdvertising);
        uiLog("Waiting..","Bluetooth Connection");
        setInterval(stepCount, 30000);
        setInterval(batteryPercentage, 5000);
        Bangle.on('accel', onAccel);
        Bangle.on('HRM-raw', onHRM);
        Bangle.setHRMPower(1, "app");
  • The app works fine when i launch it from the WebIDE,

    How do you upload from web IDE, to ram or storage?

    however, when installing it from the apploader and then "reloading", i suddenly have code duplicated in ram, therefore functions being called twice.
    So e.g.
    in ram it is like this:
    Bangle.on("accel", onAccel);
    Bangle.on("accel", onAccel);

    Where/how do you look and see this? In the web IDE left console field? Does it happen immediately on first launch or after an extra reload? Can the code be duplicated more than twice so you have e.g. three instances of the accel listener?

  • I guess you have a fork of the repo set up, could you link to that? 🙂

    edit: found it https://github.com/sfnk/BangleApps :)

  • I guess this is the app.js file in question?: https://github.com/sfnk/BangleApps/blob/­master/apps/00emerno/app.js

    What happens if you uncomment the setUI code but don't add the remove handler?

    1. Uploading to ram
    2. 'Download from RAM' in the webide, there you can see the duplication.
    3. It happens when i do the install default apps for example. Then after completion it requires a reload. At that point the Problem exists.
    4. I did not see 3x or more yet. But i will test this in 1-2 hours.
    5. Will check the setui possibility and report back.

    Thanks for the Quick response so far!

  • Can you explain a bit more what you do? So you 'install default apps', then install your app as the only clock app, and then you long-press the button on the watch to reload, connect with the Web IDE and when you view what's in RAM you see your code in there twice?

    Or are there other steps involved?

    One thing is you could have saved to flash once accidentally with the IDE which would overwrite the default code that runs with your app - but doing an 'install default apps' or even reinstalling the bootloader should fix that

  • For sure, sorry for any confusion.

    1. I install "default apps" -> this already installs my app as clock app, then you get prompted to "reload" or set it in the apploader to automatically reload. No further install from the WebIDE.
    2. Connect with the WebIDE - "Download from RAM" shows this duplicated code.
    3. Prints in the WebIDEs console are also duplicated, so is behaviour of the app, e.g. buzzing executed twice (multiple times?)

    I will try what @Ganblejs suggested now and report back.
    edit: this showed no different behaviour.

    Edit: the duplication is only present for


    2x my code, 1x code from the widget?

    var bleServiceOptions = { "uart": true };
    NRF.on("connect", function () {WIDGETS["bluetooth"].draw();});
    NRF.on("connect", function () {connected=true;uiLog("connected");});
    NRF.on("connect", function () {connected=true;uiLog("connected");});
    NRF.on("disconnect", function () {WIDGETS["bluetooth"].draw();});
    NRF.on("disconnect", function () {connected=false;uiLog("disconnected");N­RF.eraseBonds(onBondErased);});
    NRF.on("disconnect", function () {connected=false;uiLog("disconnected");N­RF.eraseBonds(onBondErased);});
    NRF.on("bond", function (status) {uiLog("bond: "+status);if(status=="success"){connecte­d=true;}else{connected=false;}});
    NRF.on("bond", function (status) {uiLog("bond: "+status);if(status=="success"){connecte­d=true;}else{connected=false;}});
    NRF.on("advertising", function (isAdvertising) {uiLog("advertising: "+isAdvertising);});
    NRF.on("advertising", function (isAdvertising) {uiLog("advertising: "+isAdvertising);});
  • Ahh, ok, as you've changed a bunch of stuff in your app loader, is it at all possible that you've got the code defined again somewhere else?

    So Widgets, but also boot code (which runs for every app)

    You could try searching all js files with:

    require("Storage").list().filter(f=>f.en­dsWith(".js")).forEach( f => {
      if (require("Storage").read(f).includes('"c­onnect"')) print(f+" contains connect");

    that searches for the text "connect" but you could extend it to search for some other more useful search phrase

  • no, cannot imagine it being literally duplicated. Also not finding any evidence for it.

    this is the generated print:

    bootupdate.js contains connect
    00emerno.app.js contains connect
    widbt.wid.js contains connect
  • update, i found a way around it, probably exposing a bug?

    i did the follwing to avoid duplicate appstart basically.

    E.on('init', startApp);


    function startApp(){

    The "bug" that listeners are added twice is still there, but this avoids it.

  • Ahh - you're calling the function once, and then asking Espruino to call the function again with E.on('init',. I don't think that's really a bug.

    As you're executing the file from flash, you might as well just remove the E.on('init', startApp); line, since when your app starts is run it's going to call startApp(); anyway.

    E.on('init', and the onInit function are really there for other Espruino devices where you can develop the app in RAM and then type save() to effectively 'hibernate' your app to flash memory. Then when your app 'wakes' the E.on('init' gets called - but that's not something we do on Bangle.js. There's a bit of info on that at https://www.espruino.com/Saving

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview

Bangle JS 2 code is duplicated after install from apploader

Posted by Avatar for sfnk @sfnk