0

I'm trying to create an extension for chrome browser that'll display the battery level of the system (and do couple other stuff) with the BatteryStatusAPI. At first I'm just trying to display the battery level using simple canvas, but it doesn't seem to work.

manifest:

    {
    "manifest_version": 2,

    "name": "Battery",
    "description": "This extension shows the battery stats of the current device.",
    "version": "1.0",

    "browser_action": {
        "default_icon": "battery_full.png",
        "default_title": "Click Here!"
    },

    "background": {
        "scripts": ["icon_changer.js"]
    }
}

JavaScript:

var battery;
navigator.getBattery()
    .then(function (b) {
        battery = b;
    }
);

function drawIcon() {
    var clockCanvas = document.createElement("canvas");
    clockCanvas.height = 19;
    clockCanvas.width = 19;

    var clockContext = clockCanvas.getContext("2d");
    clockContext.textAlign = "center";
    clockContext.textBaseline = "middle";
    clockContext.font = "9px Arial";
    clockContext.fillText(battery.level, 9, 10);

    chrome.browserAction.setIcon({
        imageData: clockContext.getImageData(0, 0, 19, 19)
    });
}

drawIcon();

What do you think the problem is?

galah92
  • 3,621
  • 2
  • 29
  • 55
  • 1
    What's the value of b inside the callback function? Add a `console.log(b);` there. And read https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron – rsanchez Apr 11 '16 at 16:36
  • `Uncaught ReferenceError: b is not defined`. Having read about asynchronous flow, I still don't understand why "getBattery()" doesn't get executed like the rest of the asynchronous code. – galah92 Apr 11 '16 at 21:16
  • No, I mean inside `function (b) { ... }`. – rsanchez Apr 11 '16 at 21:20
  • My bad. I'm getting a BatteryManager object exactly as I should. – galah92 Apr 11 '16 at 21:24
  • You can call `drawIcon()` from inside that function and it should work. – rsanchez Apr 11 '16 at 21:26
  • Perfect. But why is that? `bettery` was introduce out of `getBattery()` scope. – galah92 Apr 11 '16 at 21:31
  • Read the question and answers I linked in my first comment. – rsanchez Apr 11 '16 at 21:32

1 Answers1

0

You should know for Navigator.getBattery().then(funcRef), funcRef is a function to be called when the battery promise returned by navigator.getBattery gets resolved. Due to asynchronicity, when you call drawIcon, getBattery() may have not been resolved then funcRef will not be executed, which means battery is undefined.

You should move drawIcon function inside funcRef.

var battery;
navigator.getBattery()
    .then(function (b) {
        battery = b;
        drawIcon();
    }
);

function drawIcon() {
    // Your logic here
}
Haibara Ai
  • 10,703
  • 2
  • 31
  • 47