chrome extension storage api syntax - google-chrome-extension

chrome.storage.sync.set({'overlayColor': color});
var get = chrome.storage.sync.get('overlayColor',function());
Why do I get "Uncaught SyntaxError: Unexpected token )" for the 2nd line??
By the way, if I take away the call back function in get function, the error becomes:
extensions::StorageArea:35 Uncaught Error: Invocation of form get(string) doesn't match definition get(optional string or array or object keys, function callback)
at normalizeArgumentsAndValidate (extensions::schemaUtils:115:11)
at StorageArea.self.(anonymous function) [as get] (extensions::StorageArea:35:14)
at HTMLInputElement.changeOverlayColor (chrome-extension://neihdeocppgagfakakclajlmbgognbbc/option.js:9:35)
at Object.fireEvent (chrome-extension://neihdeocppgagfakakclajlmbgognbbc/jscolor.js:240:7)
at Object.dispatchChange (chrome-extension://neihdeocppgagfakakclajlmbgognbbc/jscolor.js:675:9)
at HTMLDocument. (chrome-extension://neihdeocppgagfakakclajlmbgognbbc/jscolor.js:667:8)

The function is missing the curly braces. You will need to replace function() with function() {}
var get = chrome.storage.sync.get('overlayColor',function() {});
The function doesn't return the data so instead of storing the result in a variable, you will want to put the logic needing the values in the callback
chrome.storage.sync.get('overlayColor',function(data) {
// use data here
});

Function is not properly declared. Correct syntax is as following:
chrome.storage.sync.get('overlayColor', function (result) {
var get = result.overlayColor;
});

Related

nodejs http listener argument must be a function

Attempting to pass a responseHandler from a require rather than having it in the same file but getting error listener argument must be a function. console.log the require return, returns a function, so I don't see the issue?
var responseHandler = require("./downloader.js");
log(responseHandler); // Logs [Functions: responseHandler)
request = https.get(fileUrl, responseHandler); // Error "listener" argument must be a function (according to the log line above, it is!?)
If I swap out line 1 for the contents of downloader.js all works fine...
Content of downloader.js is just
var responseHandler = function(response){
// some code to process response.statusCode
response.on('data',function(chunk){//stuff});
response.on('error',function(e){//stuff});
response.on('end',function(e){//stuff});
}
exports.responseHandler = responseHandler;
I would like to keep the main file clean and small and have this working as a require, ideas?
If you want to only export the function you can do it with:
module.exports = responseHandler;
Then the imported value will be the function rather than an object with a function value:
var responseHandler = require("./downloader.js");
You will need to try doing:
request = https.get(fileUrl, responseHandler.responseHandler);
You're exporting an object that has a function called responseHandler, so you need to call it directly
Either you can export only function without name
module.exports = (response)=> {
// some code to process response.statusCode
response.on('data',function(chunk){//stuff});
response.on('error',function(e){//stuff});
response.on('end',function(e){//stuff});
}

Express / Jade / Pug: Calling a javascript object's functions

While I can pass an object's data, I don't know how to pass/call an object's functions.
route.js:
router.get('/', function(req, res, next) {
let test = {}; // passing an object called test
test.hello = function() { //the test object has a method I want to
console.log('hello'); //call on the browser
}
res.render('home.jade', { test:test });
On the .jade page:
//- let test = !{test}; //renders as [object Object]
let test = !{JSON.stringify(test, null, 4)}; //renders empty obj
test.hello();
console.log('test', test);
Console message:
Uncaught TypeError: test.hello is not a function
Rendered source file:
//- let test = [object Object];
let test = {};
test.hello();
console.log('test', test);
An example of what works on my.jade file (what I don't want):
let test = {};
test.hello = #{test.hello};
test.hello();
This will console out 'hello'. However, I imagine that there is a way to pass and call an object's function without this workaround.
Thanks for any help.
JSON.stringify will strip away functions since JSON format does not support functions/methods. From MDN:
Functions are not a valid JSON data type so they will not work.
However, they can be displayed if first converted to a string (e.g. in
the replacer), via the function's toString method. Also, some objects
like Date will be a string after JSON.parse().
Technically you can use eval to evaluate the resulting string to a function, though this is not recommended.

How to use promise bluebird in nested for loop?

I need to use bluebird in my code and I have no idea how to use it. My code contains nested loops. When the user logs in, my code will run. It will begin to look for any files under the user, and if there are files then, it will loop through to get the name of the files, since the name is stored in a dictionary. Once it got the name, it will store the name in an array. Once all the names are stored, it will be passed along in res.render().
Here is my code:
router.post('/login', function(req, res){
var username = req.body.username;
var password = req.body.password;
Parse.User.logIn(username, password, {
success: function(user){
var Files = Parse.Object.extend("File");
var object = [];
var query = new Parse.Query(Files);
query.equalTo("user", Parse.User.current());
var temp;
query.find({
success:function(results){
for(var i=0; i< results.length; i++){
var file = results[i].toJSON();
for(var k in file){
if (k ==="javaFile"){
for(var t in file[k]){
if (t === "name"){
temp = file[k][t];
var getname = temp.split("-").pop();
object[i] = getname;
}
}
}
}
}
}
});
console.log(object);
res.render('filename', {title: 'File Name', FIles: object});
console.log(object);
},
error: function(user, error) {
console.log("Invalid username/password");
res.render('logins');
}
})
});
EDIT:The code doesn't work, because on the first and second console.log(object), I get an empty array. I am suppose to get one item in that array, because I have one file saved
JavaScript code is all parsed from top to bottom, but it doesn't necessarily execute in that order with asynchronous code. The problem is that you have the log statements inside of the success callback of your login function, but it's NOT inside of the query's success callback.
You have a few options:
Move the console.log statements inside of the inner success callback so that while they may be parsed at load time, they do not execute until both callbacks have been invoked.
Promisify functions that traditionally rely on and invoke callback functions, and hang then handlers off of the returned value to chain the promises together.
The first option is not using promises at all, but relying solely on callbacks. To flatten your code you will want to promisify the functions and then chain them.
I'm not familiar with the syntax you're using there with the success and error callbacks, nor am I familiar with Parse. Typically you would do something like:
query.find(someArgsHere, function(success, err) {
});
But then you would have to nest another callback inside of that, and another callback inside of that. To "flatten" the pyramid, we make the function return a promise instead, and then we can chain the promises. Assuming that Parse.User.logIn is a callback-style function (as is Parse.Query.find), you might do something like:
var Promise = require('bluebird');
var login = Promise.promisify(Parse.User.logIn);
var find = Promise.promisify(Parse.Query.find);
var outerOutput = [];
return login(yourArgsHere)
.then(function(user) {
return find(user.someValue);
})
.then(function(results) {
var innerOutput = [];
// do something with innerOutput or outerOutput and render it
});
This should look familiar to synchronous code that you might be used to, except instead of saving the returned value into a variable and then passing that variable to your next function call, you use "then" handlers to chain the promises together. You could either create the entire output variable inside of the second then handler, or you can declare the variable output prior to even starting this promise chain, and then it will be in scope for all of those functions. I have shown you both options above, but obviously you don't need to define both of those variables and assign them values. Just pick the option that suits your needs.
You can also use Bluebird's promisifyAll() function to wrap an entire library with equivalent promise-returning functions. They will all have the same name of the functions in the library suffixed with Async. So assuming the Parse library contains callback-style functions named someFunctionName() and someOtherFunc() you could do this:
var Parse = Promise.promisifyAll(require("Parse"));
var promiseyFunction = function() {
return Parse.someFunctionNameAsync()
.then(function(result) {
return Parse.someOtherFuncAsync(result.someProperty);
})
.then(function(otherFuncResult) {
var something;
// do stuff to assign a value to something
return something;
});
}
I have a few pointers. ... Btw tho, are you trying to use Parse's Promises?
You can get rid of those inner nested loops and a few other changes:
Use some syntax like this to be more elegant:
/// You could use a map function like this to get the files into an array of just thier names
var fileNames = matchedFiles.map(function _getJavaFile(item) {
return item && item.javaFile && item.javaFile.name // NOT NULL
&& item.javaFile.name.split('-')[0]; // RETURN first part of name
});
// Example to filter/retrieve only valid file objs (with dashes in name)
var matchedFiles = results.filter(function _hasJavaFile(item) {
return item && item.javaFile && item.javaFile.name // NOT NULL
&& item.javaFile.name.indexOf('-') > -1; // and has a dash
});
And here is an example on using Parse's native promises (add code above to line 4/5 below, note the 'then()' function, that's effectively now your 'callback' handler):
var GameScore = Parse.Object.extend("GameScore");
var query = new Parse.Query(GameScore);
query.select("score", "playerName");
query.find().then(function(results) {
// each of results will only have the selected fields available.
});

Accessing the promise object from within the then function

I am using the Q library of node.js . I am trying to print a report which would print the query name and the result . This is what I have . The code prints "In function undefined . How do I access the value of the promise object from within the "then" function ?
var queries = ["2091 OR 2092 OR 2093",
"2061 OR 2062",
"2139 OR 2140 OR 2141"
];
var promises = new Array();
for (var i=0; i<queries.length; i++) {
promises[i]=performSearch(queries[i]);
promises[i].query = queries[i];
console.log("Outside function ", promises[i].query);
promises[i].then(function(data) {
console.log("In function ", this.query);
processSearchResults(data,this.query);
});
}
Q.allSettled(promises).then(function(results) {
endFunction();
});
This is what I have:
promises[i].then(function(data) {
console.log("In function ", this.query);
processSearchResults(data,this.query);
});
The code prints "In function undefined".
The spec mandates that the callback is called with nothing for the this value, so this will refer to the global (window) object in sloppy mode, which does not have a .query property. In strict mode you'd have gotten an exception when this was undefined.
How do I access the value of the promise object from within the "then"
function ?
There is no special method. You usually will not need to access a promise as an object, it's only a transparent value representing the single result of an asynchronous computation. All you need to do with it is to call its .then() method - and inside the callback, there's no reason to access the promise object, because the information it holds is already accessible to you (data, and the fact that the fulfillment callback was invoked).
So if you want to access your .query property, you'd have to use promises[i] as usual. However, you will need a closure for i so you'd better use map anyway and hold the query string in the closure directly instead of making it a property on a promise object:
var queries = ["2091 OR 2092 OR 2093",
"2061 OR 2062",
"2139 OR 2140 OR 2141"
];
var promises = queries.map(function(query) {
var promise = performSearch(query);
console.log("Outside function ", query);
var processedPromise = promise.then(function(data) {
console.log("In function ", query);
return processSearchResults(data, query);
});
return processedPromise; // I assume you don't want the unprocessed results
});
Q.allSettled(promises).then(function(processedResults) {
endFunction(processedResults);
});

node kriskowal/q promise stack errors on chaining promises

The following code errors out on the first .then with:
/Users/danielbyrne/working/mite_npm/mite.js:48
.then(configMan.validateSettings(parsedData))
ReferenceError: parsedData is not defined
I don't understand why this code is failing.
The call:
parseConfigurationFile(path.join(__dirname,'file.config'))
.then(validateSettings(parsedData));
The functions it calls:
function parseConfigurationFile(fileName) {
var readFile = q.nfbind(fs.readFile);
readFile(fileName,"utf-8")
.then(function(data) {
var deferred = q.defer();
// Return the Config 'settings' in JSON
deferred.resolve(JSON.parse(data));
return deferred.promise;
});
}
function vaidateSettings (data) {...}
The only way this works is if I change the function validateSettings to an anonymous function and place it inline like this :
parseConfigurationFile(path.join(__dirname,'file.config'))
.then(function(parsedData){...});
Why can i not chain named functions in this manner?
Your validateSettings call should be like this:
parseConfigurationFile(path.join(__dirname,'file.config'))
.then(validateSettings);
The reason is that the validateSettings needs to be referenced as a function and the .then will invoke that function with the correct parameter. Doing it the way you are doing it, you receive a reference error because parsedData is not available at the time the function call is bound.

Resources