0

I'm working on a chrome extension which converts the pries on a given page into the hours a user would need to work to earn that amount. The extension takes in user salary info through the pop-up window then sets it in chrome storage. That part works fine.

Where I am having issue is in accessing that value and using it to run calculations against. The JS parses through the values well and calls the convert function, but only uses the placeholder hourly value of 1 in the calculations instead of retrieving it from chrome storage. It instead seems to access chrome storage after all the parsing (I figure this out based on when the console log runs).

Do you have any idea what is causing this? I've tried moving the entire parse into its own function to be called at the end of the $(document).ready(function) but it still wouldn't grab values from chrome storage.

In content.js:

function convert(price){
    var hourly = 1;
    chrome.storage.sync.get('hourly', function(result){
        hourly = result.hourly;
        console.log(hourly);
    });
    return price / hourly;
}

var elements = document.getElementsByTagName('*');

for (var i = 0; i < elements.length; i++) {
var element = elements[i];

    for (var j = 0; j < element.childNodes.length; j++) {
        var node = element.childNodes[j];

        if (node.nodeType === 3) {
            var text = node.nodeValue;
            if (text[0] == '$'){
                if (/\s/.test(text)){
                    var price = text.substring(0, text.indexOf(' '));
                    var priceNum = text.substring(1, text.indexOf(' '));
                    var time = convert(parseFloat(priceNum));
                    var timeStr = time.toFixed(2);
                    if (text.length > 5){
                        var remainder = text.substring(4);
                        var nextPrice = remainder.indexOf('$');
                        if (nextPrice != -1){
                            var priceTwo = remainder.substring(nextPrice);
                        }
                        var priceTwo = null;
                    }
                }
                else {
                    var price = text.substring(0);
                    var priceNum = text.substring(1);
                    var time = convert(parseFloat(priceNum));
                    var timeStr = time.toFixed(2);
                }
            }
            var replacedText1 = text.replace(price, timeStr);
            if (replacedText1 !== text) {
                element.replaceChild(document.createTextNode(replacedText1 + ' hours'), node);
            }
        }
    }
}
  • chrome.* API is asynchronous. See [How do I return the response from an asynchronous call?](//stackoverflow.com/q/14220321) – wOxxOm Apr 30 '17 at 19:57
  • Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – Zig Mandel May 01 '17 at 12:20

1 Answers1

1

chrome.storage.sync.get returns result asynchronously, by callback. You can get the result by wrapping chrome.storage.sync.get in Promise, and then receive resolved data outside in then function:

function convert(price){
    var hourly = 1;
    return new Promise(function(resolve, reject) {
        chrome.storage.sync.get('hourly', function(result){
            hourly = result.hourly;
            resolve(price / hourly);
        });
    });
}

var elements = document.getElementsByTagName('*');

for (var i = 0; i < elements.length; i++) {
var element = elements[i];

    for (var j = 0; j < element.childNodes.length; j++) {
        var node = element.childNodes[j];

        if (node.nodeType === 3) {
            var text = node.nodeValue;
            if (text[0] == '$'){
                if (/\s/.test(text)){
                    var price = text.substring(0, text.indexOf(' '));
                    var priceNum = text.substring(1, text.indexOf(' '));
                    if (text.length > 5){
                        var remainder = text.substring(4);
                        var nextPrice = remainder.indexOf('$');
                        if (nextPrice != -1){
                            var priceTwo = remainder.substring(nextPrice);
                        }
                        var priceTwo = null;
                    }
                }
                else {
                    var price = text.substring(0);
                    var priceNum = text.substring(1);
                }
            }
            convert(parseFloat(priceNum)).then(function(time) {
                var timeStr = time.toFixed(2);
                var replacedText1 = text.replace(price, timeStr);
                if (replacedText1 !== text) {
                    element.replaceChild(document.createTextNode(replacedText1 + ' hours'), node);
                }
            });
        }
    }
}
rie
  • 286
  • 2
  • 5