I wonder if there is away to avoid copying references to objects when you need to create a simple object which has an array of embedded objects.The situation is as follow: I have server which accepts a JSON and applies some logic then stores the object in DB. lets say my form is for saving teams in DB. The server accepts team as json. the team has an array of TeamMember objects, my form has a simple field to enter team member info and add it to team teamMembers array. Now here is the problem, when I add a team member to array list and want to add another team member when I type into the field the added member is changed also !. I know the reason
$scope.addTeamMember=function(teamMember){
$scope.team.teamMembers.push(teamMember);
}
and it is because I put same reference into the teamMembers array so I have same object added several times.
to avoid this I should create a new team member object, copy all teamMember properties and and add it the array.
$scope.addTeamMember=function(teamMember){
var newTeamMember; /*<--- copy teamMember */
$scope.team.teamMembers.push(newTeamMember); /*and add newTeamMember*/
}
Your question says you want to "avoid deep copy", but I'm not sure that's accurate. It sounds like you just want to use angular.copy, because you need to create a copy of the team member and add that to the array:
$scope.addTeamMember = function(teamMember) {
var newTeamMember = angular.copy(teamMember);
$scope.team.teamMembers.push(newTeamMember);
};
This is the best documentation available
https://docs.angularjs.org/api/ng/function/angular.copy
there is a live example as well on the page which is self illustrative.
I personally use this:
function copyObjToObj(source, destination) {
if(!angular.equals(source,destination)){
if (!!destination)
angular.copy(source, destination);
else
destination = angular.copy(source);
}
return destination;
}
var destination = copyObjToObj(sourceObj, destination);
Related
Normally what we do is like
const hash = new Map()
hash.set(key,value)
And when we want to retrieve the information just
hash.get(specificKey)
One of the benefits that Map has is that we can put whatever we want as key or value.
I'm trying to set a multiple value of keys on the "key" part of the map, that's not the problem is later when I want to get the information
Example:
[
{name:"Pedro",email:"test1#gmail.com"},
{name:"Anibal",email:"test2#gmail.com"},
]
I want to create the key of the map with both properties of the object (name, email), and the value is ALL the iterated register so...
const hash = new Map()
for (register of registers) {
const { name, email } = register
hash.set([name, email], register)
}
The problem is when I want to GET the register by one of the properties on the key.
We know that the key could be ["Pedro","test1#gmail.com]
How I can get the value of the Map if the key I want to get could be just "Pedro" or just "test1#gmail.com"
It is possible? :(
Thank you
___________________-
Answer to #Kevin Kinney
Thank you for answering. The idea that I want to do is to avoid this;
I dont want to have a find inside the map. Any different approach?
One idea, if you know only a few of the properties would be used as keys
const hash = new Map()
for (register of registers) {
const { name, email } = register
hash.set(name, register)
hash.set(email, register)
}
This will allow fast access to the value in the map, but increases the memory usage.
Otherwise I don't think a hashmap is the right idea if you don't know what key you will be expecting to use.
No, this is not possible
You want access in a non-standard way so what you can do is create two mappings for each value. One goes from pedro and one goes from test1#gmail.com
Then when you need to retrieve the value you can get it by either
I am facing an issue with object property changes in angular JS.
For example I have an array of objects.
$scope.ex1 = [{"name":"Ethel Price","gender":"female","company":"Enersol"},
{"name":"Claudine Neal","gender":"female","company":"Sealoud"},
{"name":"Beryl Rice","gender":"female","company":"Velity"},
{"name":"Wilder Gonzales","gender":"male","company":"Geekko"},
{"name":"Georgina Schultz","gender":"female","company":"Suretech"},
{"name":"Carroll Buchanan","gender":"male","company":"Ecosys"},
{"name":"Valarie Atkinson","gender":"female","company":"Hopeli"},
{"name":"Schroeder Mathews","gender":"male","company":"Polarium"},
{"name":"Lynda Mendoza","gender":"female","company":"Dogspa"},
{"name":"Sarah Massey","gender":"female","company":"Bisba"}]
I have a form where I show the data in a list format to display it am using angular-datatable.
When a user clicks on list items am storing that particular object in an array.
For example the user selects two items from the above list am keeping that two objects in other variable like below:
$scope.selected = [{"name":"Lynda Mendoza","gender":"female","company":"Dogspa"},
{"name":"Sarah Massey","gender":"female","company":"Bisba"}];
The issue is when I change some properties in $scope.selected the changes are reflecting automatically in $scope.ex1 object.
Like below:
$scope.selected[0].name = "Rakesh rekala"
The above change will reflect in $scope.ex1 array to that particular item.
How to restrict this scenario is there any way to solve this.
Javascript objects are mutable, use angular.copy to deep copy your source object array to a variable and then use the variable to push objects into the selected array
You should change your push line.
$scope.selected.push($scope.ex1[0]);
$scope.selected[0].name = "Test"; //ex1 will change
$scope.selected.push(angular.copy($scope.ex1[1]));
$scope.selected[1].name = "Test2"; //It's ok!
http://jsfiddle.net/ms403Ly8/124/
In the docs I see a lot of examples using index values as a part of the key name for a particular item --- but I don't understand how this is a consistent way to model your data.
For example let's say I have a list of articles:
https://gigablox.firebaseio.com/articles/
article1
article2
article3
When I'm ready to add article4 I know I can use:
var length = Object.keys($scope.articles).length;
And using AngularFire 0.5.0 I can save it with:
var name = 'article' + length + 1;
$scope.articles[name] = $scope.article;
$scope.articles.$save(name);
But what happens if I:
$scope.articles.$remove('article2');
And add another record using the same approach? We're likely to create duplicate key names.
To add a little complexity, let's add a single relationship and say that each article has comments.
What is the correct way to model this data in a Firebase collection?
Please use $add and let Firebase automatically generate chronologically ordered lists for you.
var ref = new Firebase("https://gigablox.firebaseio.com/articles/");
$scope.articles = $firebase(ref);
$scope.addArticle = function() {
$scope.articles.$add($scope.article);
}
$scope.removeArticle = function(id) {
$scope.articles.$remove(id);
}
Firebase automatically creates key names when you call $add. You can iterate over the key names using ng-repeat:
<div ng-repeat="(key, article) in articles">
<div ng-model="article"><a ng-click="removeArticle(key)">Remove</a></div>
</div>
EDIT: You should follow the suggestion from #Anant if you want an array-based collection.
However, for this specific scenario as outlined by #Dan Kanze, if you want to pull the key out of the URL (as would be done for a content management system, etc), you should generate your own keys unique to the content. For example, if you know that article names need to be unique, create a slug function that will:
Lowercase the article name
Replace spaces with underscores
etc..
If the article name changes, you would not delete the old entry. Instead, create a new entry in Firebase and use the old key to point to the new location for 301 redirects, etc.
To be honest, I'm not quite sure where to start with this question.
I'll describe the situation: I am in the process of making a level editor for an HTML5 game. The level editor is already functional - now I would like to save/load levels created with this editor.
Since this is all being done in Javascript (the level editor as well as the game), I was thinking of having the save simply convert the level to a JSON and the load, well... un-jsonify it.
The problem is - the level contains several types of objects (several different types of entities, several types of animation objects, etc...) Right now, every time I want to add an object to the game I have to write an unjsonify method specifically for that object and then modify the level object's unjsonify method so it can handle unjsonifying the newly defined type of object.
I can't simply use JSON.parse because that just returns an object with the same keys and values as the original had, but it is not actually an object of that class/prototype. My question is, then, is there a correct way to do this that does not require having to continuously modify the code every time I want to add a new type of object to the game?
I would create serialise/deserialise methods on each of your objects to put their state into JSON objects and recover it from them. Compound objects would recursively serialise/deserialise their children. To give an example:
function Player {
this.weapon = new Weapon();
}
Player.prototype.serialise = function () {
return {'type': 'Player', weapon: this.weapon.serialise()};
}
Player.deserialise = function(json_object) {
var player = new Player();
player.weapon = Weapon.deserialise(json.weapon);
return player;
}
Obviously in real code you would have checks to make sure you were getting the types of objects that you expect. Arrays and simple hash objects could be simply copied during serialisation/deserialisation though their children will often need to be recursed over.
I have some JSON objects I'd like to store in a map for the lifetime of my app. For example, my app shows a listing of Farms. When a user clicks one of the Farm links, I download a Farm representation as JSON:
Farm 1
Farm 2
...
Farm N
every time the user clicks one of those links, I download the entire Farm object. Instead, I'd like to somehow make a global map of Farms, keyed by their ID. Then when the user clicks one of the above links, I can see if it's already in my map cache and just skip going to the server.
Is there some general map type like this that I could use in jquery?
Thanks
What about a JavaScript object?
var map = {};
map["ID1"] = Farm1;
map["ID2"] = Farm2;
...
Basically you only have two data structure in JavaScript: Arrays and objects.
And fortunately objects are so powerful, that you can use them as maps / dictionaries / hash table / associative arrays / however you want to call it.
You can easily test if an ID is already contained by:
if(map["ID3"]) // which will return undefined and hence evaluate to false
The object type is the closest you'll get to a map/dictionary.
var map={};
map.farm1id=new Farm(); //etc
farmMap = {};
farmMap['Farm1'] = Farm1;
...