Setting data in Local Storage/function usage - javascript

I'm attempting to simply save a string to Chrome's Local Storage, but I can't seem to do it. It could be that I've got the wrong idea about function argument implementation (after 3 years, I think I might be getting it) but any help getting this code to work would be appreciated. I wanted to make it as dynamic as possible, allowing me to take the id of any text input field I write and change the stored string appropriately.
Here's the code I've got so far:
function setData() {
dataToStore = document.getElementById('txtStore').value;
return dataToStore;
}
function storeData(data) {
localStorage.setItem('input', data);
}
btnStore.addEventListener('click', storeData(setData), false);
Is my implementation of function arguments a bit backwards? I really thought I had it this time..

When you write:
btnStore.addEventListener('click', storeData(setData), false);
storeData(setData) is executing immediately at the beginning (when you bind the click event). Therefore, it will pass the initial value of your input which is probably empty.
So you should call setData, when you store the Data:
function setData() {
dataToStore = document.getElementById('txtStore').value;
return dataToStore;
}
function storeData() {
localStorage.setItem('input', setData());
}
btnStore.addEventListener('click', storeData, false);

you would have to do this:
function setData() {
dataToStore = document.getElementById('txtStore').value;
return dataToStore;
}
function storeData(dataFunct) {
localStorage.setItem('input', dataFunct());
}
btnStore.addEventListener('click', storeData(setData), false);

you can use without argument
function setData() {
dataToStore = document.getElementById('txtStore').value;
return dataToStore;
}
function storeData() {
var data = setData();
localStorage.setItem('input', data);
}
btnStore.addEventListener('click', storeData(), false);

You're saving the value in setData, which is a function, not the value returned from the function. You have to invoke the function to get the return value.
function storeData(data) {
vare returnedData = data()
localStorage.setItem('input', data);
}
with your current code you'd have to use the above snippet. But it would make more sense to retrieve the data before invoking storeData, and not pass the function.

You need to differentiate between function invocations and function references.
btnStore.addEventListener('click', storeData(setData), false);
An event is assigned a callback - i.e. reference to a function - but you're passing it the return value of setData, which is a string, not a function.
function setData() {
dataToStore = document.getElementById('txtStore').value;
return dataToStore;
}
function storeData() {
localStorage.setItem('input', setData());
}
btnStore.addEventListener('click', storeData, false);

You should simplify it a bit using more descriptive names for your functions:
function getDataFromElement(id){
dataToStore = document.getElementById(id).value;
return dataToStore;
}
function storeData(data) {
localStorage.setItem('inputData', data);
}
function retrieveData() {
return localStorage.getItem('inputData');
}
btnStore.addEventListener('click', storeData(getDataFromElement('txtStore')), false);
This way is more generic and you can even reuse it for other elements, improve it turning that 'inputData' into a parameter.
You could also add a check to verify that local storage is available before using it:
function canStorage(){
return (typeof(Storage) !== "undefined") ? true : false;
}

It is a good idea to batch your reads and writes, say one read per page and one write per page unload. It does depends on your use case, however, storing data in memory ie. data structure until some less frequent commit action.
To write data to Window.localStorage.
localStorage.setItem(k, v);
To read data from storage
localStorage.getItem(k);
Update:
A snippet of a module I wrote in gist which provides basic functions such as;
get
set
delete
flush
has
and a few chainable functions.
Hope this helps.

Related

Calling a nested function present inside JQuery declaration

I have a function called "destination" nested in scrip1.js file. If I add this file at the end of webpage using , how can I trigger it at the next step? Here are some contents of script1.js.
script1.js
$.something = function(element, options) {
function start() {
function destination(arg1, arg2..) {
$.notify(some args);
}
}
$("body").on("click", ".notify-btn", function (event) {
event.preventDefault();
destination(some args);
});
someOtherFunction();
start();
}
$.fn.something = function (options) {
return this.each(function () {
if (undefined == $(this).data("something")) {
var plugin = new $.something(this, options);
$(this).data("something", plugin);
}
});
};
I tried this, but is not working. Chrome console is showing error about this function.
<script type="text/javascript" src="script1.js"></script>
<script>
$.fn.something().destination();
</script>
I can not change this script1.js, so any possible way?
There's no specific connection between variables declared during function execution - and how the rest of the world sees the result of execution. So this code:
function start() {
function destination(arg1, arg2..) {
$.notify(some args);
}
}
start();
... lets destination value (remember, functions in JS are first-class citizens) go away when start() completes its execution. That's actually quite convenient if you want to encapsulate some implementation details and hide it from users; this technique (also known as Module pattern) was often used in pre-class world to implement private properties in vanilla JavaScript.
However, all the values returned from a function can be reused. For example, here...
$.something = function(element, options) {
function start() {
function destination(arg1, arg2..) {
$.notify(some args);
}
return {
destination
};
}
return start();
}
... you make destination function a part of object that is returned from start(). Now $.something returns an object, too; that means it can be reused:
var plugin = new $.something(this, options);
// ...
plugin.destination('some', 'args');
If you're afraid changing the return value might hurt someone, you can try to assign value of destination to $.something object itself as its property, like this:
$.something = function(element, options) {
function start() {
function destination(arg1, arg2..) {
$.notify(some args);
}
return destination;
}
// ...
const destination = start();
$.something.destination = destination;
}
The returned value is not modified, yet function is accessible. Still, that's not actually a good workaround; the biggest issue is that any subsequent calls on $.something will rewrite the value of that function, which might be not a good thing if its execution depends on some scoped variables.
While technically there's a way to fetch destination function code by parsing $.something source code, I really doubt it's worth the effort in your case.

TypeError: "listener" argument must be a function. Using npm pixelmatch in node JS [duplicate]

How do I pass a function as a parameter without the function executing in the "parent" function or using eval()? (Since I've read that it's insecure.)
I have this:
addContact(entityId, refreshContactList());
It works, but the problem is that refreshContactList fires when the function is called, rather than when it's used in the function.
I could get around it using eval(), but it's not the best practice, according to what I've read. How can I pass a function as a parameter in JavaScript?
You just need to remove the parenthesis:
addContact(entityId, refreshContactList);
This then passes the function without executing it first.
Here is an example:
function addContact(id, refreshCallback) {
refreshCallback();
// You can also pass arguments if you need to
// refreshCallback(id);
}
function refreshContactList() {
alert('Hello World');
}
addContact(1, refreshContactList);
If you want to pass a function, just reference it by name without the parentheses:
function foo(x) {
alert(x);
}
function bar(func) {
func("Hello World!");
}
//alerts "Hello World!"
bar(foo);
But sometimes you might want to pass a function with arguments included, but not have it called until the callback is invoked. To do this, when calling it, just wrap it in an anonymous function, like this:
function foo(x) {
alert(x);
}
function bar(func) {
func();
}
//alerts "Hello World!" (from within bar AFTER being passed)
bar(function(){ foo("Hello World!") });
If you prefer, you could also use the apply function and have a third parameter that is an array of the arguments, like such:
function eat(food1, food2) {
alert("I like to eat " + food1 + " and " + food2 );
}
function myFunc(callback, args) {
//do stuff
//...
//execute callback when finished
callback.apply(this, args);
}
//alerts "I like to eat pickles and peanut butter"
myFunc(eat, ["pickles", "peanut butter"]);
Example 1:
funct("z", function (x) { return x; });
function funct(a, foo){
foo(a) // this will return a
}
Example 2:
function foodemo(value){
return 'hello '+value;
}
function funct(a, foo){
alert(foo(a));
}
//call funct
funct('world!',foodemo); //=> 'hello world!'
look at this
To pass the function as parameter, simply remove the brackets!
function ToBeCalled(){
alert("I was called");
}
function iNeedParameter( paramFunc) {
//it is a good idea to check if the parameter is actually not null
//and that it is a function
if (paramFunc && (typeof paramFunc == "function")) {
paramFunc();
}
}
//this calls iNeedParameter and sends the other function to it
iNeedParameter(ToBeCalled);
The idea behind this is that a function is quite similar to a variable. Instead of writing
function ToBeCalled() { /* something */ }
you might as well write
var ToBeCalledVariable = function () { /* something */ }
There are minor differences between the two, but anyway - both of them are valid ways to define a function.
Now, if you define a function and explicitly assign it to a variable, it seems quite logical, that you can pass it as parameter to another function, and you don't need brackets:
anotherFunction(ToBeCalledVariable);
There is a phrase amongst JavaScript programmers: "Eval is Evil" so try to avoid it at all costs!
In addition to Steve Fenton's answer, you can also pass functions directly.
function addContact(entity, refreshFn) {
refreshFn();
}
function callAddContact() {
addContact("entity", function() { DoThis(); });
}
I chopped all my hair off with that issue. I couldn't make the examples above working, so I ended like :
function foo(blabla){
var func = new Function(blabla);
func();
}
// to call it, I just pass the js function I wanted as a string in the new one...
foo("alert('test')");
And that's working like a charm ... for what I needed at least. Hope it might help some.
I suggest to put the parameters in an array, and then split them up using the .apply() function. So now we can easily pass a function with lots of parameters and execute it in a simple way.
function addContact(parameters, refreshCallback) {
refreshCallback.apply(this, parameters);
}
function refreshContactList(int, int, string) {
alert(int + int);
console.log(string);
}
addContact([1,2,"str"], refreshContactList); //parameters should be putted in an array
You can also use eval() to do the same thing.
//A function to call
function needToBeCalled(p1, p2)
{
alert(p1+"="+p2);
}
//A function where needToBeCalled passed as an argument with necessary params
//Here params is comma separated string
function callAnotherFunction(aFunction, params)
{
eval(aFunction + "("+params+")");
}
//A function Call
callAnotherFunction("needToBeCalled", "10,20");
That's it. I was also looking for this solution and tried solutions provided in other answers but finally got it work from above example.
Here it's another approach :
function a(first,second)
{
return (second)(first);
}
a('Hello',function(e){alert(e+ ' world!');}); //=> Hello world
In fact, seems like a bit complicated, is not.
get method as a parameter:
function JS_method(_callBack) {
_callBack("called");
}
You can give as a parameter method:
JS_method(function (d) {
//Finally this will work.
alert(d)
});
The other answers do an excellent job describing what's going on, but one important "gotcha" is to make sure that whatever you pass through is indeed a reference to a function.
For instance, if you pass through a string instead of a function you'll get an error:
function function1(my_function_parameter){
my_function_parameter();
}
function function2(){
alert('Hello world');
}
function1(function2); //This will work
function1("function2"); //This breaks!
See JsFiddle
Some time when you need to deal with event handler so need to pass event too as an argument , most of the modern library like react, angular might need this.
I need to override OnSubmit function(function from third party library) with some custom validation on reactjs and I passed the function and event both like below
ORIGINALLY
<button className="img-submit" type="button" onClick=
{onSubmit}>Upload Image</button>
MADE A NEW FUNCTION upload and called passed onSubmit and event as arguments
<button className="img-submit" type="button" onClick={this.upload.bind(this,event,onSubmit)}>Upload Image</button>
upload(event,fn){
//custom codes are done here
fn(event);
}
By using ES6:
const invoke = (callback) => {
callback()
}
invoke(()=>{
console.log("Hello World");
})
If you can pass your whole function as string, this code may help you.
convertToFunc( "runThis('Micheal')" )
function convertToFunc( str) {
new Function( str )()
}
function runThis( name ){
console.log("Hello", name) // prints Hello Micheal
}
You can use a JSON as well to store and send JS functions.
Check the following:
var myJSON =
{
"myFunc1" : function (){
alert("a");
},
"myFunc2" : function (functionParameter){
functionParameter();
}
}
function main(){
myJSON.myFunc2(myJSON.myFunc1);
}
This will print 'a'.
The following has the same effect with the above:
var myFunc1 = function (){
alert('a');
}
var myFunc2 = function (functionParameter){
functionParameter();
}
function main(){
myFunc2(myFunc1);
}
Which is also has the same effect with the following:
function myFunc1(){
alert('a');
}
function myFunc2 (functionParameter){
functionParameter();
}
function main(){
myFunc2(myFunc1);
}
And a object paradigm using Class as object prototype:
function Class(){
this.myFunc1 = function(msg){
alert(msg);
}
this.myFunc2 = function(callBackParameter){
callBackParameter('message');
}
}
function main(){
var myClass = new Class();
myClass.myFunc2(myClass.myFunc1);
}

Returning values in Javascript to C# HTML file

Here is my issue, I have a javascript function in a .js file that performs some actions, gathers information, and uses a callback. The callback function is also a javascript function but resides in a .cshtml file. I am have difficulties returning a value from my .js javascript function to my .cshml javascript callback function.
Here is a little sample code...
my .js function which I would like to return a value from:
function returnVal(itemID, onCompleteCallback) {
//get vals from DB
onCompleteCallback();
}
my .cshtml script that calls the previous function and I need to get the returned value is a button click even:
updateBtn.onclick = function(e) {
if(action==1) {
returnVal(itemID, OnCompleted);
}
I have tried 2 methods, neither has worked. I have tried returning a value within the "returnVal" function which doesn't seem to results in anything being returned. I have also tried passing a variable as type var and setting it within the returnVal function, it was my understanding that primitives are passed by value (and thus this wouldn't work) but objects are passed by reference and so I thought this would work. At any rate, neither was successful. Bellow are examples of how I have tried the aforementioned 2 methods:
Method 1:
function returnVal(itemID, onCompleteCallback) {
//get vals from DB
onCompleteCallback();
return x;
}
updateBtn.onclick = function(e) {
if(action==1) {
x = returnVal(itemID, OnCompleted);
}
}
Method 2:
function returnVal(x, itemID, onCompleteCallback) {
//get vals from DB
onCompleteCallback();
}
updateBtn.onclick = function(e) {
if(action==1) {
var x;
returnVal(x, itemID, OnCompleted);
}
}
In both cases 'x' is not set. I hope I have provided enough details, any help would be greatly appreciated.
I think you want something like
function returnVal(itemId, onComplete){
var data = getValueFromDatabase();
onComplete(data);
}
updateBtn.onclick = function(e) {
if(action==1) {
returnVal(itemID, function(data){
// Do something with returned value i.e. 'data'
});
}
}

a javascript function called without arguments

I am trying to understand a JavaScript code.
Banana.reloadUser is being called inside a function without any arguments:
function(data) {
if (!data.result.success) {
alert(data.result.message)
} else {
/*do something*/
Banana.testData = data;
Banana.reloadUser();
}
}
Banana.reloadUser defined like this:
Banana.extend({
reloadUser: function(cb, data) {
var that = this,
done = function(d) {
$.extend(that.user, d);
if ($.isFunction(cb)) {
cb(d)
}
that.trigger("user.reloaded", [d])
};
if (data) {
done.apply(banana, [data])
} else {
/*do something*/
}
}
})
'reloaduser' is being called to save the userinfo data in the localstorage. So whenever user do something new from its account 'reloaduser' saves the new information into the localstorage.
My question is since Banana.reloadUser is being called without arguments how is it supposed to pick its arguments ?
Note: This is a part of a big JavaScript/jquery code so in case this information is not enough please ignore the question.
The big Javascript code does contain another function
Banana.reloadUser(function() {
try {
Banana.trigger('start', [$]);
}catch(e) { }
try {
$('[data-deferred]').deferredImage();;
}catch(e) { }
});
started = true;
};
If you call a JavaScript function without arguments then all its parameters receive a value of undefined (not null which is a different value).
So calling
Banana.reloadUser()
is just the same as:
Banana.reloadUser(undefined, undefined)
In your code this is perfectly ok, the condition:
if ($.isFunction(cb)) {
will fail because undefined is not a function, and later on the condition:
if (data) {
will also fail because undefined is treated as equivalent to false when it appears somewhere that a boolean value is expected.
It is exactly similar to the below call,
Banana.reloadUser(undefined,undefined);

Phonegap wait for database transaction to complete

I'm creating a Phonegap application that will perform differently on first run. The way that I am detecting the first run is by seeing of one of the database tables exists. As you can probably tell from the code below, I am checking for the error that is (probably) indicating that the table already exists, thus proving that this is not the application's first run.
function databaseExists(){
var exists;
database.transaction(function(tx){
tx.executeSql('CREATE TABLE GLOBAL (uid, property, value)');
}, function(err){
exists = true;
}, function(){
exists = false;
});
return exists;
}
My problem, however, is that the asynchronous execution of the Javascript code means that the function returns its value before the success (or error) function has set it's value.
This function is called in the initialising stage of the application:
if (databaseExists()){
// Do Something
}
And therefore must return the value rather than execute the function in the success callback of the transaction.
Is there a way to force the execution to wait until the database transaction is complete or return the value through the database.transaction object?
Thanks in advance,
Jon
You need to write it in callback form:
var dataBaseExists(yep, nope) {
database.transaction(function(tx) {
tx.executeSql('CREATE TABLE GLOBAL (uid, property, value)');
}, function(){
if (yep) {
yep.apply(this, arguments);
}
}, function(){
if (nope) {
nope.apply(this, arguments);
}
});
};
var itDoes = function() {
console.log("great");
};
var itDoesNot = function() {
console.log("what a pity");
};
databaseExists(itDoes, itDoesNot);
You need callbacks, but if don't need checking existment of your tables, you can do that easily with localStorage.
e.g.
if(localStorage.getItem('init') === null){
//init
localStorage.setItem('init', true);
}
You will avoid dealing with database.
and maybe this gonna be helpful "CREATE TABLE IF NOT EXISTS..."
I know there's gonna be programmers don't like my solution, but I love it!
var myfEspereti=false;
function Espereti(pStatus)
{
if (pStatus==="wait")
{
myfEspereti = true;
while(myfEspereti)
{
}
}
else if (pStatus==="go")
{
myfEspereti=false;
}
}
and then call Espereti ("wait") when you want to wait for an async call. Inside the async call, when it's finish, call Espereti ("go") and that's it!

Categories