I have some code like this
$scope.grabItems = function(data) {
data.model = ['test'];
console.log($scope.ui.projects);
}
$scope.ui.projects = [];
$scope.grabProjects = function() {
$scope.grabItems({model: $scope.ui.projects});
}
I'm trying to change the $scope.ui.projects variable using the parameter of another function (this is so that I can write an abstract grabItems function using any variable).
The problem is it looks like the data.model = ['test'] isn't changing the $scope.ui.projects variable at all but is creating a brand new variable.
How would I modify the outer variable in a reusable way like this?
Note that $scope.ui.projects could potentially be any variable.
You are not actually not changing $scope.ui.projects, Try like this
$scope.grabItems = function(data) {
data.model = ['test'];
console.log($scope.ui.projects);
}
$scope.ui.projects = [];
$scope.grabProjects = function() {
$scope.grabItems($scope.ui.projects);
}
If it's not clear, share what is your expected object.
You could achieve it by pushing items into the array:
$scope.grabItems = function(data) {
if(!angular.isArray(data.model))
throw new Error('Array expected');
data.model.length = 0; // empty array
data.model.push('test'); // push items
console.log($scope.ui.projects);
}
$scope.ui.projects = [];
$scope.grabProjects = function() {
$scope.grabItems({model: $scope.ui.projects});
}
Related
I am trying to assign a array inside a variable in javascript. But i am getting error like this. Could you please correct me where i have missed.
"TypeError: newItems.json is undefined"
var newItems = [];
if ($$('.selectvals:checked').length > 0) {
var i=0;
$$('.selectvals:checked').each(function (e) {
var row = e.parentNode.parentNode;
var jsonVals = row.down('.jsonval').value;
var jsonPaymentVals = row.down('amount').value;
newItems['json'][i] = jsonVals;
newItems['amount'][i] = jsonPaymentVals;
i++;
});
}
You need initialize right it, like this:
var newItems = {
json:[],
amount:[]
}
I want to pass an object into a function as a parameter, and assign things to properties of that object, then those would be accessible outside of the function. But I am not to clear on how it is done.
At first I thought it could be done using callbacks, but it was made clear to me that JavaScript does not work that way. I eventually managed to get it working, and the undefined error messages went way. But I wanted to now pass an array through the function. How can this be done? This is what I've done so far, but it doesn't seem to be working.
var journey = {};
journey['waypointsArrayItem'] = new Array();
setupAddress(journey)
function setupAddress(journey) {
var waypointsItem = $('.timeline-item.active-item > .timeline-status > .waypoints').text().substring(4);
journey.waypointsArrayItem = [];
journey.waypointsArrayItem = listToArray(waypointsItem, ', ');
for (var i = 0; i < waypointsArray.length; i++) {
journey.waypointsArrayItem[i] = journey.waypointsArrayItem[i];
}
}
You are copying array items to themselves. Copy from the waypointsArray array to the journey.waypointsArrayItem array:
function setupAddress(journey) {
var waypointsItem = $('.timeline-item.active-item > .timeline-status > .waypoints').text().substring(4);
var waypointsArray = listToArray(waypointsItem, ', ');
for (var i = 0; i < waypointsArray.length; i++) {
journey.waypointsArrayItem[i] = waypointsArray[i];
}
}
Depending on what you need, you could also just replace the entire array:
function setupAddress(journey) {
var waypointsItem = $('.timeline-item.active-item > .timeline-status > .waypoints').text().substring(4);
journey.waypointsArrayItem = listToArray(waypointsItem, ', ')
}
Assigning properties to an object in a function is the same as assigning properties outside of a function.
function addName(obj, name) {
obj.name = name;
}
var bob = {};
console.log(bob.name); // undefined
addName(bob, 'Bob');
console.log(bob.name); // 'Bob'
How do I grant access to inner properties of objects in the right way? This is what does break my application:
I have an object that handles an array (simplified here):
function ListManager() {
var list = [],
add = function (element) {
list.push(element);
},
clear = function () {
list = [];
};
return {
add: add,
clear: clear,
list : list
};
};
But I get this when using it:
var manager = new ListManager();
manager.add("something");
manager.clear();
console.log(manager.list.length); // <= outputs "1"!
Stepping through the code shows, that within the clear method, list becomes a new array. But from outside the ListManager the list ist not cleared.
What am I doing wrong?
This is because clear sets the value of var list, not the .list on the object returned from ListManager(). You can use this instead:
function ListManager() {
var list = [],
add = function (element) {
this.list.push(element);
},
clear = function () {
this.list = [];
};
return {
add: add,
clear: clear,
list : list
};
}
Using your current structure, you could do:
function ListManager() {
var list = [],
add = function (element) {
list.push(element);
},
clear = function () {
list = [];
};
getList=function(){
return list;
}
return {
add: add,
clear: clear,
list : list,
getList: getList
};
};
var manager = new ListManager();
manager.add("something");
console.log(manager.getList()); // ["something"]
manager.clear();
console.log(manager.getList()); // []
function ListManager() {
var list = [],
add = function (element) {
this.list.push(element);
},
clear = function () {
this.list = [];
};
return {
add: add,
clear: clear,
list : list
};
};
var manager = new ListManager();
manager.add("something");
manager.clear();
console.log(manager.list.length); // <= now outputs "0"!
As has already been explained, your issue is that when you do list = [], you are changing the local variable list, but you aren't changing this.list as they are two separate variables. They initially refer to the same array so if you modified the array rather than assigning a new one to just one of the variables, they would both see the change.
Personally, I think you're using the wrong design pattern for creating this object that just makes things more complicated and makes it more likely you will create problems like you did. That design pattern can be useful if you want to maintain private instance variables that are not accessible to the outside world, but it creates a more complicated definition and maintenance if everything is intended to be public.
One of my programming goals is to use the simplest, cleanest way of expressing the desired functionality.
So that end, since everything in this object is intended to be public and accessible from outside the object, this is a whole lot simpler and not subject to any of the types of problems you just had:
function ListManager() {
this.list = [];
this.add = function(element) {
this.list.push(element);
}
this.clear = function() {
this.list = [];
}
}
Or, perhaps even use the prototype:
function ListManager() {
this.list = [];
}
ListManager.prototype = {
add: function(element) {
this.list.push(element);
},
clear: function() {
this.list = [];
}
};
Hello I've used this patter to get a static variable
var uniqueID = (function() {
var id = 0; // This is the private persistent value
// The outer function returns a nested function that has access
// to the persistent value. It is this nested function we're storing
// in the variable uniqueID above.
return function() { return id++; }; // Return and increment
})(); // Invoke the outer function after defining it.
Now I'm trying to clone this function, but backup and the original still return sequential values. How can i "freeze" the status of the function when copy it?
Thanks
OK, something like this extremely convoluted contraption should work (fiddle, http://jsfiddle.net/dPLj6/):
var uniqueIdFunction = function(initialValue) {
var id = initialValue || 0;
var result = function() { return id++; };
result.clone = function(){ return uniqueIdFunction(id); }
return result;
};
var uniqueId1 = uniqueIdFunction();
Use the clone method to get a clone. The original will keep it's own internal id value. The clone will take its initial internal id from the clone source.
Here is a function that generates unique id generators:
var createGenerator = function(id) {
var id = id || 0;
return function() { return id++; };
}
var g1 = createGenerator();
var g2 = createGenerator();
console.log(g1(), g1(), g1());
console.log(g2(), g2());
console.log(g1());
console.log(g2());
// OP's cloning scenario
var freezeId = g1();
var clone = createGeenrator(freezeId);
console.log(g1(),g1());
console.log(clone());
#pax162's answer is more in line with what the OP wants to do. I just decided to post the more normal way of doing it.
I've been thinking about how to display the newest array (because the array list would update from time to time.). I think there's a default function to it but I can't find it. Anyone knows it?
var bgImg = new Array();
bgImg[0] = "background.jpg";
bgImg[1] = "background2.jpg";
bgImg[2] = "background3.jpg";
bgImg[3] = "background4.jpg";
If you want the last element of the array,
>>> a = ['background1','background2'];
["background1", "background2"]
>>> b = a[a.length-1]
"background2"
You shouldn't need to manually assign indexes. Just do bgImg.push('background2.jpg'), and it will mutate the array for you. In your case the syntax would be...
var last = bgImg[bgImg.length-1]
If you want the newest then you need to make a variable and set it with whatever you update when you push the newest one, if it doesn't become the last one.
You could create a little object to handle this for you.
function creatImageState() {
var images = [];
return {
get latest() {
return images[images.length - 1];
},
set latest (value) {
images.push(value);
}
};
}
var s = creatImageState();
s.latest = "a.png";
s.latest = "b.png";
alert(s.latest);
IE doesn't support getters and setters so you probably need to use this.
function creatImageState() {
var images = [];
return {
getLatest : function() {
return images[images.length - 1]
},
setLatest : function(value) {
images.push(value);
}
};
}
var s = creatImageState();
s.setLatest("a.png");
s.setLatest("b.png");
alert(s.getLatest());