How do I set an object property within a Backbone model - javascript

Right, so I have a number of Backbone models going on, and in one of them I have an object that has a set of keys and values, of which the values are modified by locating the key from a string.
So I started out with code that was built on the below principle, I am quite comfortable with how and why this code will output true:
var boundData = {
text: 'value'
}
var key = 'text';
return (boundData[key] === 'value');
So to set the value of the property, I would do something like:
boundData[key] = 'new value';
Then I decided to translate all of my existing classes to Backbone models. And the problem that I hit, was that I can no longer change my properties with an equals operator, instead I use the set method provided by Backbone for models. This method takes a string as the first parameter, this string identifies the key for the variable that I am trying to change.
this.set("boundData[" + settings.name + "]", new OpenCore.boundData(settings));
This does not seem to work, and neither does this:
this.set("boundData." + settings.name, new OpenCore.boundData(settings));
SOLVED IT. Whilst I was writing out the question, I figured out a way to do it. But thought I would leave it here in case others run into the same problem.
This is a solution, whilst it may not be the best (I'd be interested if someone could get the original way sorted.), but it seems to work.
var boundData = this.get('boundData'); //Create a reference of the object with get().
boundData[settings.name] = new OpenCore.boundData(settings); //Update this reference.
//The change will be reflected in the original instance or you can just:
this.set('boundData', boundData);
Hope this helps someone else out!

This is a solution, whilst it may not be the best (I'd be interested if someone could get the original way sorted.), but it seems to work.
var boundData = this.get('boundData'); //Create a reference of the object with get().
boundData[settings.name] = new OpenCore.boundData(settings); //Update this reference.
//The change will be reflected in the original instance or you can just:
this.set('boundData', boundData);
Hope this helps someone else out!

Related

Calling array names dynamically inside jQuery

I'm pretty sure this question is going to get negative response as many people have already asked it in SO. But trust me I have read every single answer of every single question none helped.
I know that in jquery you can put the array key name dynamically like this: somearray1["abc" + variable] but I'm not looking for that. I want to call the array name dynamically like:
var i=1;
console.log( "somearray" + i["abc" + variable] )
Can someone tell me how is it possible? I cannot put it in another array and call that as I'm building a very dynamic script, so I must need to call the array name dynamically.
Any help will be highly appreciated.
Normaly, your array depend from this.
this["somearray" + i]["abc" + variable]
var bob1 = [1,2,3];
var name = "bob";
console.log(this[name+"1"][0])
I'm not sure exactly what you're asking here from your example. Do you want to console.log the value held at a dynamically changing position of "somearray"? If so, array positions are numerical indices (e.g. somearray[1]) and cannot be accessed via strings.
Are you trying to access an object property (e.g. someObject1["abc" + variable]) alternatively?
If it's an object property you are trying to access with changing parameters, you might want to try using ES2015 template literal syntax.
let i = 1;
let someObjectName = `someObject${i}`;
console.log( someObjectName[`abc${variable}`] );
That way the concatenation of the object name and its property will happen dynamically. I hope this helps.

AngularJS - Change the $scope object

I have a very weird issue.
I have an object under the $scope
I using an angular.foreach loop but there is a problem.
when I'm trying to set a value depending on langKey(where langKey is 'en' or 'el') all the values are being updated by ingoring the langKey.
$scope.finalObject[langKey]['servicesElements'][itemKey]['name'] = something;
the problem still exists when I simply use the console in order to change the values from there.
I'm setting the value 'myCustomText' to the el version of the object
$scope.finalObject.el['servicesElements'][itemKey]['name'] = 'myCustomText'
BUT if i run this one
$scope.finalObject.en['servicesElements'][itemKey]['name']
it returns 'myCustomText' with no reason because what I changed was the el version not the en.
Is this normal? I'm totally stuck
Thank you in advance
Well guys,
The problem was that I had declared the two different objects with the same source.
$scope.finalObject.el.servicesElements = something;
and
$scope.finalObject.en.servicesElements = something
I didn't have seen that before, but the browser was behaving like I have typed
$scope.finalObject.en.servicesElements = $scope.finalObject.el.servicesElements = something
and in every change of the one the other was following.
(in php is called pointer)
The solution was to use the angular's copy function
http://docs.angularjs.org/api/angular.copy
So I simply used this SO answer Reset a model with angular.js did this
$scope.tmpVar = something;
$scope.finalObject.en.servicesElements = angular.copy($scope.tmpVar);
$scope.finalObject.el.servicesElements = angular.copy($scope.tmpVar);

JavaScript colon operator

I am trying to learn JavaScript. After reading this page: What does ':' (colon) do in JavaScript?
I tried to replace
var store = new dojo.data.ItemFileReadStore({
url: "countries.json"
});
with
var store = new dojo.data.ItemFileReadStore();
store.url = "countries.json";
It does not work. Can any one please point out the mistake, or explain the correct use of the Colon operator?.
Thanks.
That's not a fair comparison, although you're almost there.
var store = new dojo.data.ItemFileReadStore({
url: "countries.json"
});
//Creates a new store object, passing an anonymous object in with URL
// property set to "countries.json"
The alternative without the colon operator is:
var props={};
props.url="countries.json"
var store = new dojo.data.ItemFileReadStore(props);
//Does same as above but doesn't use :
Not this isn't the only use of : in JavaScript though, it can also be used in the ternary operator (alert(b==c?'equal':'not equal');) and in labels (for example in case statements)
The first passes url parameter to the so-called constructor or the object, which may do something under the hood with it - for example assign it to other variable or property, for example "url2".
The second assigns url property of that object and you don't know if it will be used.
In first code you are creating a new object and passing it to the function as an argument.
While in second part you are running the function and then, you are setting property of store object.
They are totally different thing, as you are not calling function with argument, so it might not run properly. and you are setting return of function to object. not setting property.
In this case, the object literal in your first example is being used to pass in a set of options to the constructor. Constructing the ItemFileReadStore and then trying to set those options may not be equivalent since it may need them in order to build the object to begin with.
You'd need to do something like this to replace : with =:
var options = {};
options.url = 'countries.json';
var store = new dojo.data.ItemFileReadStore(options);
If the second way isn't working, you're probably not returning an Object with new dojo.data.ItemFileReadStore(); which prevents you from extending it with dot syntax. If you have an Object, adding to it like that will work fine.
Edit: Misread, in one you're passing an argument, in the other you're assigning to the return value, so two different things, I'll leave the above as an FYI.
The dojo.data.ItemFileReadStore object probably requires that the url property be present while the object is being created. If that's not the case, then the object doesn't allow you to set that property manually after you have already initialized the object.
The colon is used in JSON to designate the different between a key and a value, when you pass an object structure ({}).

How can I copy element by 'pass by value' not by 'pass by reference'

Below is the snippet of the code. Basically, 'this.leaves' is a array. And I want to shift first array element, make copy of it (called frontLeaf), and unshift it to the original array, change some attributes from copied element, and put that element to the parent array element.
var frontLeaf = this.leaves.shift();
this.leaves.unshift(frontLeaf);
frontLeaf.leftChild = tmp;
frontLeaf.rightChild = this;
this.parent.leaves.push(frontLeaf);
My problem is that frontLeaf seems to be passed by reference that when I assign
frontLeaf.leftChild = tmp;
frontLeaf.rightChild = this;
above two lines of code seems to affect both elements in this.leaves and this.parent.leaves... So, How can I resolve this problem?
Javascript passes all objects by reference. The only way to do what you're looking for is to create an entirely new object, do a deep copy and then push it.
See this post for a sample solution using jQuery.
Yes, in JavaScript objects are always passed by reference. If you want a copy of an object, you'll have to write a deep-copy routine yourself.
I'm not sure exactly what you're trying to do (what is tmp? what is this? what is this.leaves an array of?), but maybe there is a way to do it without needing a copy?
Here's what I did when faced the same issue:
var newObj = JSON.parse(JSON.stringify(oldObj));

JS: capture a static snapshot of an object at a point in time with a method

I have a JS object I use to store DOM info for easy reference in an elaborate GUI.
It starts like this:
var dom = {
m:{
old:{},
page:{x:0,y:0},
view:{x:0,y:0},
update:function(){
this.old = this;
this.page.x = $(window).width();
this.page.y = $(window).height();
this.view.x = $(document).width();
this.view.y = window.innerHeight || $(window).height();
}
I call the function on window resize:
$(window).resize(function(){dom.m.update()});
The problem is with dom.m.old. I would have thought that by calling it in the dom.m.update() method before the new values for the other properties are assigned, at any point in time dom.m.old would contain a snapshot of the dom.m object as of the last update – but instead, it's always identical to dom.m. I've just got a pointless recursion method.
Why isn't this working? How can I get a static snapshot of the object that won't update without being specifically told to?
Comments explaining how I shouldn't even want to be doing anything remotely like this in the first place are very welcome :)
this is a reference to an object. You're not storing a copy of an object. You're storing a reference to that object. If you want a copy you'll need to copy the properties by hand. The easy way is to use $.extend():
this.old = $.extend({}, this);
OK right, the terminology is 'deep' copy. I would've thought it was the other way round (just get an impression rather than the object itself). So anyway Cletus is right but the syntax is:
this.old = $.extend(true,{},this)
And apparently 'snapshot' is 'clone' in developer lingo.

Categories