I am not getting expected values through this code, please help me to identify the bug in this code. I am newbie to java script, I doubt the problem might be due to object creation or object scope. I debugged it in several ways but unable to identify the problem.
Also please tell me if the data I am creating is in JSON format or not. If not what is the equivalent JSON format ?
PS.id = -1;
PS.data = {
formData:[]
};
PS.setDef = [];
PS.item = {};
if(cond){
PS.item.Name = "From";
PS.item.Type = "STRING";
PS.setDef.push(PS.item);
alert(PS.setDef[0].Name);
PS.item.Name = "To";
PS.item.Type = "STRING";
PS.setDef.push(PS.item);
alert(PS.setDef[1].Name);
}//here alerts are coming properly. getting 'from' and 'to' in alerts
PS.data.formData.push({"id":id++, "setDef":[PS.setDef[0]]});
PS.data.formData.push({"id":id++, "setDef":[PS.setDef[1]]});
//expected id 0
alert(PS.data.formData[0].id);
//expected name 'from'
alert(PS.data.formData[1].setDef[0].Name);
//expected id 1
alert(PS.data.formData[1].id);
//expected name 'to'
alert(PS.data.formData[1].setDef[1].Name);
Instead of getting 0 and 1 as ID's and names as 'from' and 'to' I am getting following values
-1
0
to
to
Update 1 : here PS means page scope which is already declared, edited the alerts to print variables.
Your code had a couple of logical errors and a typo. This is the corrected version (changes have been marked in comments with **HERE**)
PS.id = -1;
PS.data = {
formData:[]
};
PS.setDef = [];
if(cond){
// *** HERE ***
// Your code was creating just one object instance in
// PS.item, pushing it, mutating and pushing it again
// The "alert" call was apparently correct just because
// it was done before mutating the object. Just moving
// both alerts at the end would have shown the problem.
PS.setDef.push({Name: "From", Type: "STRING"});
alert(PS.setDef[0].Name);
PS.setDef.push({Name: "To", Type: "STRING"});
alert(PS.setDef[1].Name);
}
// **HERE**
// id++ increments a value but returns the value BEFORE the increment.
// Thus formData[0] is expected to have .id == -1, not 0.
// If you want the value AFTER the increment then use ++id.
PS.data.formData.push({"id":++id, "setDef":[PS.setDef[0]]});
PS.data.formData.push({"id":++id, "setDef":[PS.setDef[1]]});
//expected id 0
alert(PS.data.formData[0].id);
//expected name 'from'
// *** HERE ***
// In the original code there is a typo (formData[1] instead of formData[0])
alert(PS.data.formData[0].setDef[0].Name);
//expected id 1
alert(PS.data.formData[1].id);
//expected name 'to'
alert(PS.data.formData[1].setDef[1].Name);
You just referenced PS.item twice in this part of your code:
PS.item.Name = "From";
PS.item.Type = "STRING";
PS.setDef.push(PS.item);
alert(PS.setDef[0].Name);
//changing the value of PS.item
PS.item.Name = "To";
PS.item.Type = "STRING";
PS.setDef.push(PS.item);
alert(PS.setDef[1].Name);
You can chnage your code this way and go happy with the results:
//creating first instance
PS.item = {};
PS.item.Name = "From";
PS.item.Type = "STRING";
PS.setDef.push(PS.item);
alert(PS.setDef[0].Name);
//creating the second instance
PS.item = {};
PS.item.Name = "To";
PS.item.Type = "STRING";
PS.setDef.push(PS.item);
alert(PS.setDef[1].Name);
Got the idea?
There are 2 things here.
First for id, change the code to the following,
PS.data.formData.push({"id":++PS.id, "setDef":[PS.setDef[0]]});
PS.data.formData.push({"id":++PS.id, "setDef":[PS.setDef[1]]});
Since your id starts with -1 when u assign id++ to id, it firsts assigns the value currently in id and then increments the value of id, hence you get -1 and 0.
Second, when you push PS.item, you are actually passing the reference to the object and not the actual object. Hence when you are updating the value of PS.item, it gets reflected in both the places. Try to create a new object and push it, instead of overwriting the old one.
Use PS.item = {}; to create a new object, before assigning the values. This should work.
Related
I am using two different array object initialPermissionArr[item.id] and newPermissionArr[roleId] in two different functions
function(item){
vm.initialPermissionArr[item.id] = item.permissions.map(function (permission) {
permission.status = true;
return permission;
});
}
staticArr[item.id] = item.permissions.map(function (permission) {
permission.status = true;
return permission;
});
newpermissionArr[item.id] = vm.initialPermissionArr[item.id];
Below function updates the array, if same object is found it updates the status and if new object is found it pushes to newPermissionArr
function onChanageOfPermission(roleId,item) {
var flag = false ;
for (var key in newpermissionArr[roleId]){
if(newPermissionArr[roleId][key].id == item.id){
flag = true;
newPermissionArr[roleId][key].status = item.status;
break;
}
}
if (!flag) {
newPermissionArr[roleId].push(item);
}
}
So when newPermissionArr[roleId][key].status = item.status; is updated it also update the status in the initialPermissionArr[item.id] also.
And initial declaration is
var newPermissionArr = [];
var staticArr = [];
where for eg item is
{
roleId : 1,
permissions : [{"name": "A", "id" : 1},{ "name" : "B", "id" : 2 }]
}
I need initial object Array to remain same and at the end i need to compare the initial array with the modified array and need to find the reference however on updating the status it updates in both array. How to avoid this ?
The arrays reference the same object. To modify just one of them, you should use slice() function for clone the array:
newpermissionArr[item.id] = vm.initialPermissionArr[item.id].slice();
This is happening because of following line of code
newpermissionArr[item.id] = vm.initialPermissionArr[item.id];
Here object is passed by reference, so whenever newpermission is updated intialpermission will also be updated.
To fix this just copy the intialPermissionArr to newPermissionArr.
Unfortunately,plain javascript does not have any function like angular.copy. So you will have to do this in following way-
newrPermissionArr[item.id] = JSON.parse(JSON.stringify(vm.intialPermissionArr[item.id]));
this should fix your problem.
When you assign something to a and b and it is a pointer in memory to object c. Then as soon as you change it to c2 both a and b will get c2 from that point as they were just pointers to same location.
Hi there before I start I did try looking through the search about writing variables so if this has been asked and answered then I do apologise but this is baffling me ....
So here goes ..
example of what I am talking about
var i = e[ab]
var n = e[cd][ef]
var t = e[cd][gh]
I know that when I want var i I can put e.ab but how would I go about writing var n and var t
So assuming your object looks like this (based on your description, it sounds like you want to access an object which is the property of another object), and you want to access them through the indexer properties (which would be a property of a property).
var e = {
ab : "variableOne",
cd : {ef:"ef object"},
gh : {ij:"ij object"},
}
var i = e["ab"]
//if these are properties, then you need to add quotes around them
//to access a property through the indexer, you need a string.
var n = e["cd"]["ef"]
var t = e["gh"]["ij"]
console.log(i);
console.log(n);
console.log(t);
console.log("this does the same thing:")
console.log(e.ab);
console.log(e.cd.ef);
console.log(e.gh.if);
In your example the object would look like
//e is the parameter, but I show it as a variable to show
// it's relation to the object in this example.
e = {
now_playing: {artist:"Bob Seger"; track:"Turn the Page"}}
}
this is different than an array of arrays:
var arr = [
['foo','charlie'],
['yip', 'steve'],
['what', 'bob', 'jane'],
];
console.log(arr[0][0]); //foo
console.log(arr[0][1]); //charlie
console.log(arr[1][0]); //yip
console.log(arr[1][1]); //steve
console.log(arr[2][2]); //jane
https://jsfiddle.net/joo9wfxt/2/
EDIT:
Based on the JSON provided, it looks like parameter e in the function is assigned the value of the item in the array. With your code:
this line will display: "Rock you like a hurricane - Nontas Tzivenis"
$(".song_title .current_show span").html(e.title);
and this line will display: "Rascal Flatts - Life is a Highway".
$(".song_title .current_song span").html(e.np);
If it's not displaying you might want to double check your JQuery selectors. This ".song_title .current_song span" is selecting it by the classes on the element.
I think you are in need of a bit of a refresher on basic JavaScript syntax. Here's how you can assign an "empty object" to a variable, then start to assign values to it's properties:
e = {}
e.ab = {}
e.cd = {}
e.cd.ef = "data"
or you can use the associative array syntax for property access:
e = {}
e["ab"] = {}
e["cd"] = {}
e["cd"]["ef"] = "data"
You see the latter is using the object e like a two-deep associative array. Is that what you are looking to do?
JavaScript is not strongly typed. So an Array "a" could contain objects of different types inside.
var a = [ "a value", [1, 2, 3], function(){ return 5 + 2;}];
var result = a[0]; //get the first item in my array: "a value"
var resultOfIndexedProperty = a[1][0]; //Get the first item of the second item: 1
var resultOfFunc = a[2](); //store the result of the function that is the third item of my array: 7
Hope this helps a little.
So close to nailing this but falling at the last hurdle... Need some clarification.
Basically, I want to load in the array value of a key in a given object as a variable, if other variable strings match.
Perhaps it's better if I give it some context:
js:
var ArraysObject = {
"new" : [
"http://productPageBanners/UK/2new/c0bkn201001u0000.jpg",
"http://productPageBanners/UK/2new/h0ihd60100000001.jpg",
"http://productPageBanners/UK/2new/l0flj20100000001.jpg",
"http://productPageBanners/UK/2new/m0lrt60100000001.jpg",
"http://productPageBanners/UK/2new/p0gps50106000001.jpg"
],
"knives" : [
"http://productPageBanners/UK/3aknives/c0bkn201001u0000.jpg",
"http://productPageBanners/UK/3aknives/n01pl20100000001.jpg"
]
};
var url = jQuery(location).attr('href'); // get the current url, outputs URL
var icatRef = url.split("/")[4]; // capture the icatRef from url, outputs ==>"knives"
// Get properties on the object ArraysObject as an array
var icatTitlesInObject = Object.keys(ArraysObject); // outputs the keys in object, i.e ==> ["new","knives"]
Then I want to check that if the indexOf that array is equal to the icatRef (pulled from the URL), then create a new variable which stores the relevant array from the correct key.
Something like:
if (icatsArray.indexOf() == icatRef) {
var currentarraytorandomise = ArraysObject.keys.this};
// if "knives" is the icatRef then currentarraytorandomise ==> [
// "http://productPageBanners/UK/3aknives/c0bkn201001u0000.jpg",
// "http://productPageBanners/UK/3aknives/n01pl20100000001.jpg"
// ]
However that last bit is wrong because currentarraytorandomise is undefined.
I hope that's clear! Quite new to OOP.
You're using indexOf incorrectly, try something like this:
var currentarraytorandomise, index = icatsArray.indexOf(icatRef);
if (index >= 0) {
currentarraytorandomise = ArraysObject[icatsArray[index]];
}
But you could just try to get the array directly:
ArraysObject[icatRef]
Without extracting keys or anything. If icatRef doesn't exist, you'll get undefined.
I'm trying to achieve a function that makes the user able to save a mathematical formula that uses static variables that I've already created and save them with Local Storage.
Then the script fetches that formula from the Local Storage, does the math and displays the results on a table.
I have everything in order, except the fetching part;
as localStorage.getItem() returns a string, and converting it with parseFloat()/parseInt() only returns the first integer or NaN.
Both of this messes up the expected the results.
Is there any way I can get Objects from localStoage that contains both integers and variables?
Heres an example of a formula that should work, fetched by 5 localStorage.getItem() requests.
avgFrags*250
avgDmg*(10/(avgTier+2))*(0.23+2*avgTier/100)
avgSpots*150
log(avgCap+1,1.732)*150
avgDef*150
Any ideas or alternatives?
EDIT:
Each line represents the output of a getItem() request;
form_frag = localStorage.getItem('formula_frag');
form_dmg = localStorage.getItem('formula_dmg');
form_spot = localStorage.getItem('formula_spot');
form_cap = localStorage.getItem('formula_cap');
form_def = localStorage.getItem('formula_def');
localStorage store in a key-value store where every value is pushed to a string. If you are certent that you are handling "integers" you can push the string to a number:
var avgFrags = +localStorage.getItem('avgFrags'); // The + infront pushes the string to number.
I'm not completely sure that I understand your question.
(+"123") === 123
You can convert easily convert your strings to functions if you know the variable names before hand using Function(). The first parameter(s) are your function arguments and the last is your function body.
var func1 = Function('avgFrags', 'return avgFrags * 250;');
This is equivalent to:
function func1(avgFrags) {
return avgFrags * 250;
}
Known Function Signature
If you know what variable names will be used for each item in local storage then it should be easy for you to do what you want with function:
// from your edited question
form_frag = localStorage.getItem('formula_frag');
form_dmg = localStorage.getItem('formula_dmg');
// ... create functions
var fragsFunc = Function('avgFrags', form_frg );
var dmgFunc = Function('avgDmg', 'avgTier', form_dmg );
// ... get frags
var frags = fragsFunc (10); // frags = 2500; // if sample in storage
Unknown Function Signature
Now if you have a limited amount of variable names and you don't know which ones will be used with each function then you can do something like:
var avgFrags, avgDamage, avgTier, avgSpots, avgCap, avgDef;
// ... get from storage
form_frag = localStorage.getItem('formula_frag');
form_dmg = localStorage.getItem('formula_dmg');
// ... create functions
var fragsFunc = Function('avgFrags', 'avgDamage', 'avgTier', 'avgSpots', 'avgCap', 'avgDef', form_frag);
var dmgFunc = Function('avgFrags', 'avgDamage', 'avgTier', 'avgSpots', 'avgCap', 'avgDef', form_frag);
// ... get frags, only the first argument is used, but we don't know that.
var frags = fragsFunc (avgFrags, avgDamage, avgTier, avgSpots, avgCap, avgDef); // frags = 2500; // if sample in storage
You can make this simpler by having just one variable passed into the function which is an object that holds all of the arguments that can be passed to the function. Just have to make sure that the function writer uses that object.
var settings = {
avgFrags: 10,
avgDamage: 50,
// ...
};
var fragsFunc = Function('s', 's.avgFrags * 250');
var frags = fragsFunc (settings);
Getting parts with an regex
I am assuming that the above will get the job done, that you don't really want an object with variable names and numbers and operators.
If you just need the variable names and numbers (and operators) you can use a regex for that.
([a-z_$][\w\d]*)|([0-9]*\.?[0-9]+)|([^\w\d\s])
You can use that to create an array with each part. Also each part is grouped so you know which is a variable name, which is a number, and which is an other (parenthesis or operator)
var re = /(\w[\w\d]*)|([0-9]*\.?[0-9]+)|([^\w\d\s])/g,
match,
results;
while ((match = re.exec(localStorage.getItem('formula_frag'))) {
results.push({
text: match[0],
type: (match[1]) ? 'var' | (match[2]) ? 'number' : 'other'
})
}
You can view the output of the regex with your sample data using REY.
Yes you can set Objects in localstorage
Here is the fiddle for that - http://jsfiddle.net/sahilbatla/2z0dq6o3/
Storage.prototype.setObject = function(key, value) {
this.setItem(key, JSON.stringify(value));
}
Storage.prototype.getObject = function(key) {
var value = this.getItem(key);
return value && JSON.parse(value);
}
$(function() {
localStorage.setObject('x', {1: 2, 2: "s"})
console.log(localStorage.getObject('x'));
});
when executing the following code firebug tells me: values[this.geo.value] is undefined
what is the problem?
$.get('./RDFexamples/tin00089_test2.rdf', null, function (rdfXml) {
var rdf, json = {};
var values = new Array();
rdf = $.rdf()
.load(rdfXml)
.prefix('', 'http://ontologycentral.com/2009/01/eurostat/ns#')
.prefix('qb', 'http://purl.org/linked-data/cube#')
.prefix('rdf', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#')
.prefix('dcterms', 'http://purl.org/dc/terms/')
.prefix('sdmx-measure', 'http://purl.org/linked-data/sdmx/2009/measure#')
.where('?observation a qb:Observation')
.where('?observation dcterms:date ?date')
.where('?observation sdmx-measure:obsValue ?measure')
.where('?observation :geo ?geo')
.each(function () {
values[this.geo.value].push(this.measure.value);
//alert(this.date.value)
//alert(this.measure.value)
//alert(this.geo.value)
}
);
alert(values);
});
values[this.geo.value] is never initialized so you can't do .push because values[this.geo.value] is undefined, you first need to create an array in values[this.geo.value] before you can push things into it.
Pseudo-code example
if values[this.geo.value] == undefined {
values[this.geo.value] = []
}
values[this.geo.value].push(...)
push is a method of the Array object itself - you are calling it on a value within the Array (which has probably not been set, hence 'undefined'). It's unclear what this.geo.value is, but assuming its the index of the array item you are trying to set, your options are:
values.push(this.measure.value);
or
values[this.geo.value] = this.measure.value;