all! I've come across a dilemma. I'm creating something of a price-configurator, and basically Jquery is going to be creating a bunch of subtotal variables as the user selects certain options. All of these variables will have names that begin with sub- At the end of the code, I'd like to be able to write a line that gets each one of the sub- variables and adds its value to a grand total. Is there a way to do this, and if so, how?
There is not really a way to do this if the variables are tracked separately. If you stored them in an object, you can loop through the object using
$.each(myObject, function (key, value) {
if (key.indexOf('sub-') === 0) {
// to do
}
});
You can do this with an array, and use
myArray[myArray.length] = value
as you are looping through the form. Then loop through the array at the end to get the values you need.
Without seeing your code or pseudo-code or knowing anything about the scope of your price configurator, is there any reason why you can't create a (relatively) global grand-total variable that is accessible, scope-wise, to every code path that generates a sub- variable; and then add the value of each sub- variable to the grand total as soon as the value of the sub- variable is calculated?
Related
I have 2 variables inside an Angular component/class FilterComponent that point to an object. The first one (localStorage) stores the results of the current filtering choices that the user makes and is connected with toogle buttons with [(ngValue)]. The second one (globalStorage) gets the results of filtering choices that the user made earlier within other components (if you for example click on fruit on home page,globalStorage.food gets updated, but not the localStorage within FilterComponent). I have a method that should assign gloablStorage to localStorage when the user open the filter that looks like this:
openFilter() {
this.localStorage = this.globalStorage; //this line is responsible for strange behaviour
...
}
This works exactly like it should, but only after the apply button on filter (within FilterComponent) is clicked, which is responsible for sending the contents of localStorage to globalStorage (via next/behaviourSubject).
For some mysterious reason, before that happens, the values of toggleButtons get assign to globalStorage as well as to localStorage (although they are connected only to localStorage). Why is this happening and how can I fix it?
when you do this.localStorage = this.globalStorage; and these 2 variables are objects, it means this.localStorage now point/refer to this.globalStorage, so from now on this 2 variable will refer to 1 place.
If you just want to copy data inside it you should do a copy instead of simple assign by using either Object.assign(shallow copy) or this.local = {...this.global} for loop deep copy
Thank you all for your help. The solution (that's good enough for now) was to reassign each property:
this.localStorage.property1 = this.localStorage.property1;
this.localStorage.property2 = this.localStorage.property2;
I am having to store a large array of JavaScriptobjects, these objects need to contain a message, and a way of selecting an associated HTML element.
Currently, I've been using the the following code to add to this array:
if (field[0].id != ""){
this.selectorString = "#" + field[0].id;
}
else if (field.attr("name") != ""){
this.selectorString = "[name='" + field.attr("name") + "']";
}
I didn't want to store the entire field, as I wasn't confident on JavaScripts/JQuery memory management or how it worked. Selection strings seemed the safer option, as opposed to a large array of fields. I could then just use the stored string to perform a JQuery selection statement and manipulate the field.
The Big Question
If I store the fields, will this take up a large amount of memory, or is it purely reference to an object that is already stored somewhere in the big black hole of JavaScript of which I know little?
Is there an alternative that anyone can think of that would enable me to achieve what I'm going for. The 'fields' can be divs/spans/input fields/anything, that might not necessarily have an ID/Name - which will cause problems if I'm not storing the field.
Many thanks.
If I store the fields, will this take up a large amount of memory, or is it purely reference to an object that is already stored somewhere in the big black hole of JavaScript of which I know little?
Just a reference (the "big black hole" is called the "DOM" or "DOM tree" or sometimes "page"). But note that if you remove the element you're referring to from the DOM at some point, but still have a reference to it from a JavaScript variable, the element is kept in memory (just not in the DOM tree) until/unless you assign a new value to that variable or that variable goes out of scope.
Concrete example: Say we have this on our page:
<div id="foo">....</div>
And we have this code:
var f = $("#foo");
Now we have a jQuery object wrapped around a reference to that element. It's not a copy of the element, just a reference to it.
Now suppose we did this:
f.remove();
That div is no longer in the DOM (on the page), but it still exists because we still have a reference to it from the f variable (indirectly; f refers to a jQuery object which, in turn, refers to the element). But if that variable goes out of scope, or we assign some other value to it (for instance, f = null;), then the element is not referenced from anywhere and can be reclaimed.
If you're not removing elements from the DOM (directly, or indirectly by replacing the contents of an an ancestor of theirs), then very little memory is used to simply refer to the existing element.
I need short messages disappearing after preset time. Please see the fiddle here: http://jsfiddle.net/X88F9/1/.
It works well, what I am not sure about is the reference for each created object:
function addObject() {
new SomeObj(Math.random() * 1000 + 300);
}
it is not stored in any variable, can I just leave it as it is ? Or do I need to push them in some array ?
I also found this recommendation to put all in closures: https://stackoverflow.com/a/10246262/2969375, but not sure if necessary in my case and if yes, then how.
My answer to the question is: Javascript does not need a reference to the object to work, as proofed by your fiddle. So the question is more about if you need a reference to the object, to do other stuff with it later on. If you, for instance, would like to give the user the ability to click the temporarily display message and stop it from disappearing, than you can put all that code in a closure and do not need a reference, too. But if you would like to display the very same object again after it was removed from the DOM, than you need to store it in an array, other object, or variable, depending on your needs and ways to find it in a list.
This is my first question, probably very silly indeed :)
I have a selection of values in an array, returned from GM_listValues().
As I loop over the collection, I want to dynamically create buttons that call a function to delete the stored value, and reload the page.
deleteB.addEventListener("click", function() {deleteTrip(names[i]);pageSelect();}, false);
Above is the line I am using to attach the event to the button (deleteB). However, when I press the button, javascript tries to access the array of listValues (names) with the count variable (i). Naturally, this will not exist, as the loop is now done, and names is not global anyway.
What I want to know is if there is a way to copy the string value of names[i] while I am creating the function in the button, so as to not need a reference to names[i] in the code.
I know this is probably a really simple answer, but its got me stumped, this is some of my first work with javascript.
Thanks in advance.
Use a closure to remember the value;
function createDeleteFunc(name) {
return function(){deleteTrip(name);pageSelect();}
}
for() {
...
deleteB.addEventListener("click", createDeleteFunc(names[i]), false);
...
}
The problem is that all functions you create reference the same i variable. When they are called, they try to delete names[i], but i is now equal to names.length so it doesn't work.
The solution is to make a separate reference to names[i] for each function. This is usually done with a closure (à-la Paul's answer)
I'd really like to track variables without switching between Firebug console windows or clicking around so much, so I want to draw a runtime viewer of variable names and their corresponding values that will display on the page of the app I am building.
I'd like to two functions, show(variableName) and freeze(variableName). They will output both the variable's value and the name of the variable or object as a literal string which will serve as the text label in the viewer. freeze(variableName) is the same as show(variableName) except with a setTimeOut timer for tracking loops.
I'm sure I'm missing something basic, but I haven't found out a way to get the string that comprises the name of a value programmatically so I can use it as a label. I guess I could create the table with hardcoded labels prior to runtime and just populate it with values at runtime, but I really want to generate the table dynamically so it only has those variables I specifically want to show or freeze. Simple functions:
foo1 = "Rock";
show(foo1);
foo2 = "Paper";
show(foo2);
foo3 = "Scissors";
show(foo3);
should output this via getElementById('viewer-table'):
<table>\<tr><td>foo1</td><td>Rock</td></tr><tr><td>foo2</td><td>Paper</td></tr><tr><td>foo3</td><td>Scissors</td></tr></table>
I've tried this solution:
How to convert variable name to string in JavaScript?
and eval() but it's not working for me...I dunno, shouldn't this be easy? Getting frustrated...
Thanks,
motorhobo
I am not sure you can actually get the "name" of the variable that is being passed into a function for two reasons:
1) The variable is just an identifier. In fact, you could have multiple identifiers reference the exact same object. You are (generally) passing that reference, not any actual object.
2) The show/freeze function is going to stomp on the identifier name, either through named arguments in the function declaration or by referencing them through the arguments array.
I was trying to think if there was some clever way to use the arguments.callee or the stack property on an exception in Firefox... but I can't see anything that would expose the arguments as you desire.
What I would recommend is to simply add the name of the variable and its value to a simple object, and call one of the various jsDump methods (I prefer the one in QUnit):
function show(o) {
document.getElementById("viewer-table").innerHTML = QUnit.jsDump(o);
}
// actually use the method
show({"foo1":foo1});
There's no easy way to solve this as the called function simply doesn't know the original name of the variable. You couldn't solve this with reflection even (esp. in javascript) so you'll have to pass the name of the variable to the function too. To follow the link you posted:
function show(varObject)
{
for(name in varObject)
{
alert(name + ": " + varObject[name]);
// save both name and reference to the variable to a local "to observe array"
}
}
And call it with
var test = "xxx";
show({'test' : test});
Within the for loop you could add easy variable to a monitor array and update your gui in fixed time intervalls (you can't be notifed when a signle variable changes it's value. You need some kind of global monitor/observer which exactly you're trying to create).