Object not updating after localstorage get - javascript

In the following I try to test whether an object has been stored in localstorage, and if not to fill it with initial variables.
var TimerData = $localstorage.getObject("TimerData", "{}");
if(!TimerData.hasOwnProperty("timerState")) {
TimerData["timerState"] = "run";
TimerData["timeOutMode"] = false;
TimerData["timeOutStartDate"] = null;
console.log("test line", TimerData)
};
However, running the console at line "test line" returns {} despite that I filled TimerData with variables lines before.
$localstorage.getObject looks as follows:
getObject: function(key, fallBack) {
return JSON.parse($window.localStorage[key] || fallBack);
},
My guess is that the operation is dealing with async problems (taking data from localstorage takes longer).
How can this be overcome?

Jakee1 has the right idea but but you asked about angular...
Instead of
var TimerData = $localstorage.getObject("TimerData", "{}");
I would create local storage first, then assign a var to it.
$localStorage.$default({TimerData: {}});
var TimerData = $localStorage.TimerData;
This will only setup localStorage to {} if it doesn't exist ety

It looks like you are setting the value of "TimerData" to an empty object.
I think you can simplify this using standard js notation (you definitely dont need a special $localstorage adapter because you are using ionic). Ionic should respect standard js notation (although purely speculation on my part)
var TimerData = localStorage.get("TimerData");
if (!TimerData.timerState) {
TimerData["timerState"] = "run";
TimerData["timeOutMode"] = false;
TimerData["timeOutStartDate"] = null;
console.log("test line", TimerData)
}

Related

Assign value to global variable after $.ajax and behave like a const [duplicate]

I was tearing my hair out to get this done...particularly for an html5 detection script. I wanted a variable that is set only once and that can't be overwritten again. This is it:
var StaticConfiguration = {};
StaticConfiguration.Main = {
_html5: null
}
StaticConfiguration.getVariable = function(name) {
return StaticConfiguration.Main["_" + name];
}
StaticConfiguration.setVariable = function(name, value) {
if(StaticConfiguration.Main["_" + name] == null) {
StaticConfiguration.Main["_" + name] = value;
}
}
First, I define a global object StaticConfiguration containing all of these variables - in my case, just "html5". I set it to null, since I want to set it inside the application. To do so, I call
StaticConfiguration.setVariable("html5", "true");
It's set then. If I try to set it again, it fails - of course, since _html5 is not null anymore. So I practically use the underscore to "hide" the static variable.
This is helping me a lot. I hope it's a good approach - please tell me if not :)
First off, it's true, not "true" all strings (apart from the empty string) evaluate to true, including the string "false".
Second off, do you really need to protect data like this? There's not really any way to safely run a user's Javascript i your context anyway. There's always a way around protection like this. If offending code really cared, it could just replace the whole StaticConfiguration object anyway.
Matthew's code is a better approach to the problem, but it doesn't follow a singleton pattern, but is a class that needs to be instanciated. I'd do it more like this, if you wanted a single object with "static" variables.
StaticConfiguration = new (function()
{
var data = {}
this.setVariable = function(key, value)
{
if(typeof data[key] == 'undefined')
{
data[key] = value;
}
else
{
// Maybe a little error handling too...
throw new Error("Can't set static variable that's already defined!");
}
};
this.getVariable = function(key)
{
if (typeof data[key] == 'undefined')
{
// Maybe a little error handling too...
throw new Error("Can't get static variable that isn't defined!");
}
else
{
return data[key];
}
};
})();
Personal sidenote: I hate the "curly brackets on their own lines" formatting with a passion!
Take a look at Crockford's article on Private Members in JavaScript. You can do something like this:
var StaticConfiguration = (function() {
var html5; /* this is private, i.e. not visible outside this anonymous function */
return {
getVariable: function(name) {
...
},
setVariable: function(name, value) {
...
}
};
)();
How about:
var StaticConfiguration = new (function()
{
var data = {}
this.setVariable = function(key, value)
{
if(typeof data[key] == 'undefined')
{
data[key] = value;
}
};
this.getVariable = function(key)
{
return data[key];
};
})();
Similar to the other answer, but still allows arbitrary keys. This is truly private, unlike the underscore solution.
I'm a little curious as to why you think that you have to go to this extent to protect the data from being overwritten. If you're detecting the browser, shouldn't it only be done once? If someone's overwriting it with invalid data, then I would assume that it would be a problem in the client implementation and not the library code - does that make sense?
As a side note, I'm pretty big on the KISS principle, especially when it comes to client side scripting.
I know i'm a little late to the party but in situations like this i usually
var data;
if (data === undefined || //or some other value you expect it to start with{
data = "new static value"
};

Angular Factory Object Persisting Over Storing in Local Storage

I've got a problem that i need help with in Angular 1.4.0.
I have a factory in angular which has a complex structure and method within so i am able to restore the factory back to its original state by calling the method.
The factory looks like this.
angular.module('myApp').factory('itemFcty', function(){
var currentValues = {};
var default values {
a = 1,
b = 2,
resetData : function(){
currentValues = angular.extend(currentValues, defaultValues);
return currentValues
};
};
defaultValues.resetData();
return currentValues;
});
In order to add values to 'a' i call itemFcty.a = 2;
So this method works well when i want to overwrite all the values as and when required.
However i have been asked could i persist the data over a refresh. So i stringify the object into JSON. Like this:
localStorage.setItem('itemFcty', JSON.parse(itemFcty);
However i have hit a snag. The only data to be stored in the local storage is the
{a = 1,b = 2,}
I can add the method back in by doing this:-
itemFcty.resetData = function(){return currentValues = angular.extend(currentValues, defaultValues);}
This is the issue that now the factory does function the same way as before as i am not able to call the function as the call and return outside the default values object is not there any more i can cannot for the life of me work out how to add it back into as everything goes directly into the object as a whole.
Your help would be greatly appreciated!
/*************************EDIT *****************************/
Ok, so i think that i havent explained the point very well.
My factory looks exactly like the above. The user hits refresh. The factory is stored in local storage. I get it back from local storage. But heres the issue.
It looks like this before local storage
angular.module('myApp').factory('itemFcty', function(){
var currentValues = {};
var defaultValues = {
a : 1,
b : 2,
resetData : function(){
angular.extend(currentValues, defaultValues);
// you don't have to return the values
} // <------you can't use ; in the object properties
};
defaultValues.resetData();
return currentValues;
});
Now when i get the data out f local storage and into the factory the factory then looks like this.
angular.module('myApp').factory('itemFcty', function(){
a : 1,
b : 2,
});
I can add the reset data function back in, however as the factory does not contain current or default values, the reset data function will not work.
So basically i am asking how to make my factory, look the same as it does originally after i have reloaded data from the local storage.
Did you load the variable back from localStorage? Also, there is a typo, I'd say var default values. In general stringifying does not account for methods, because that wouldn't make sense for other languages importing them.
Problems:
var default values {, space separated variable and missing assignment operator =.
In the object you can assign values with = but :, so it will produce error { a = 1, b = 2 }.
what you can do is:
angular.module('myApp').factory('itemFcty', function(){
var currentValues = {};
var defaultValues = { // <-------should have to be declared like this
a : 1, // = should be replaced with :
b : 2, // and here too.
resetData : function(){
angular.extend(currentValues, defaultValues);
// you don't have to return the values
} // <------you can't use ; in the object properties
};
defaultValues.resetData();
return currentValues;
});

Reading a cookie(which is an object) in pure javascript

I am trying to read a cookie in plain javascript only. I'm not using any jquery cookie library.
Here's how my cookie looks:
var task_cookie = {
task1 : getTask('task1')
, task2 : getTask('task2')
, task3: getTask('task3')
, task4: getTask('task4')
, task5: getTask('task5')
};
document.cookie = "task_cookie=" + JSON.stringify(task_cookie)+";path=/;domain=.task.com";
Now, I'm trying to read the value of task_cookie later on a different page
I found this code on stackoverflow
function read_cookie(name) {
var result = document.cookie.match(new RegExp(name + '=([^;]+)'));
result && (result = JSON.parse(result[1]));
return result;
}
But this would give me the whole task_cookie.I however want to grab each key value inside the task_cookie. I want something like this:
$.cookie('task1')
$.cookie('task2')
However this is very easy in jquery after I stringify. But forsome reason I need to use pure javascript. How can I get individual values of task1 , task2 etc which are inside the task_cookie object? I'm having a hard time figuring this out :/
The function is returning the entire object, so you can just select an individual cookie from the function:
read_cookie('task_cookie')['task1'];
Or something similar. The above will just return the task1, but you can iterate through all the tasks.
Better yet, you can make the read_cookie function an object method and just return the cookie object to a property of the parent object.
var cookieHandler = {
get: function(name) {
//code to get cookies
//push to cookies array
},
cookies: []
};
That way you don't have to create a bunch of instances for a global function every time you iterate over a task.
So read the value from the cookie after you get the object.
function read_cookie(name) {
var result = document.cookie.match(new RegExp('tasj_cookie=([^;]+)'));
result && (result = JSON.parse(result[1]));
return result ? result[name] : null;
}
Better yet, use localstorage and not cookies.
localstorage.setItem("task1", getTask('task1'));
function read_storage (name) {
return localstorage.getItem(name); //might need to use JSON.parse() depending on the data
}
console.log(read_storage("task1"));

How to create javascript function lookup object?

I'm attempting to create a function lookup in Javascript essentially mapping a data type to a function that does something for that data type. Right now I have something similar to:
var Namespace = Namespace || {};
Namespace.MyObj = function () {
var stringFunc = function(someData) {
//Do some string stuff with someData
};
var intFunc = function(someData) {
//Do some int stuff with someData
};
var myLookUp = {
'string': stringFunc,
'int' : intFunc
};
return {
PublicMethod: function (dataType, someData) {
myLookUp[dataType](someData);
}
};
} ();
When I invoke Namespace.MyObj.PublicMethod(dataType, someData) I get an error that myLookUp is not defined. I'm assuming I'm not going about setting up the function lookup object correctly, but not sure how to do so. Thanks for any help.
The problem might simply be incorrect case
myLookup[dataType](someData);
should be (notice the capital U)
myLookUp[dataType](someData);
Just looked at my post after I wrote it up, stupid oversight, I'm declaring the properties as strings, instead of just properties.
....
var myLookUp = {
string: stringFunc,
int: intFunc
};
....
Fixes the issue.
Some additional follow up, in my actual code dataType is the result of a jQuery select. Don't know why or if this would be browser dependant (I'm using FireFox), but using double quotes around the property definition works, single quotes does not, and no quotes works as well. :-\

Static variable in Javascript that is set only once

I was tearing my hair out to get this done...particularly for an html5 detection script. I wanted a variable that is set only once and that can't be overwritten again. This is it:
var StaticConfiguration = {};
StaticConfiguration.Main = {
_html5: null
}
StaticConfiguration.getVariable = function(name) {
return StaticConfiguration.Main["_" + name];
}
StaticConfiguration.setVariable = function(name, value) {
if(StaticConfiguration.Main["_" + name] == null) {
StaticConfiguration.Main["_" + name] = value;
}
}
First, I define a global object StaticConfiguration containing all of these variables - in my case, just "html5". I set it to null, since I want to set it inside the application. To do so, I call
StaticConfiguration.setVariable("html5", "true");
It's set then. If I try to set it again, it fails - of course, since _html5 is not null anymore. So I practically use the underscore to "hide" the static variable.
This is helping me a lot. I hope it's a good approach - please tell me if not :)
First off, it's true, not "true" all strings (apart from the empty string) evaluate to true, including the string "false".
Second off, do you really need to protect data like this? There's not really any way to safely run a user's Javascript i your context anyway. There's always a way around protection like this. If offending code really cared, it could just replace the whole StaticConfiguration object anyway.
Matthew's code is a better approach to the problem, but it doesn't follow a singleton pattern, but is a class that needs to be instanciated. I'd do it more like this, if you wanted a single object with "static" variables.
StaticConfiguration = new (function()
{
var data = {}
this.setVariable = function(key, value)
{
if(typeof data[key] == 'undefined')
{
data[key] = value;
}
else
{
// Maybe a little error handling too...
throw new Error("Can't set static variable that's already defined!");
}
};
this.getVariable = function(key)
{
if (typeof data[key] == 'undefined')
{
// Maybe a little error handling too...
throw new Error("Can't get static variable that isn't defined!");
}
else
{
return data[key];
}
};
})();
Personal sidenote: I hate the "curly brackets on their own lines" formatting with a passion!
Take a look at Crockford's article on Private Members in JavaScript. You can do something like this:
var StaticConfiguration = (function() {
var html5; /* this is private, i.e. not visible outside this anonymous function */
return {
getVariable: function(name) {
...
},
setVariable: function(name, value) {
...
}
};
)();
How about:
var StaticConfiguration = new (function()
{
var data = {}
this.setVariable = function(key, value)
{
if(typeof data[key] == 'undefined')
{
data[key] = value;
}
};
this.getVariable = function(key)
{
return data[key];
};
})();
Similar to the other answer, but still allows arbitrary keys. This is truly private, unlike the underscore solution.
I'm a little curious as to why you think that you have to go to this extent to protect the data from being overwritten. If you're detecting the browser, shouldn't it only be done once? If someone's overwriting it with invalid data, then I would assume that it would be a problem in the client implementation and not the library code - does that make sense?
As a side note, I'm pretty big on the KISS principle, especially when it comes to client side scripting.
I know i'm a little late to the party but in situations like this i usually
var data;
if (data === undefined || //or some other value you expect it to start with{
data = "new static value"
};

Categories