Nov 8, 2012 5:09 PM
13 Posts
topic has been resolvedResolved

viewScope variable binding question

  • Category: Server Side JavaScript
  • Platform: Windows
  • Release: 8.5.3
  • Role: Developer
  • Tags:
  • Replies: 3
My viewScope variable is getting updated when I update a variable that was initiated with the value of the viewScope variable. Is this the expected behavior? I haven't noticed this happening before (perhaps I've never had this exact scenario), but I would like to fully understand how this is intended to work so that I can code appropriately.
 
Here's my code: 
 
1) I set a viewScope variable when the page loads as follows -- the value should never be updated unless the user refreshed the whole page: 

<xp:this.beforePageLoad><![CDATA[#{javascript:

var result = DbLookupArray('', applicationScope.mainDBPath, 'cache', 'unique', '', 'lvwUserProfilesbyRole', "Leasing Agent", 4);

if (result) {

var dmData:java.util.HashMap = new java.util.HashMap;

for (var dm in result) {

colKey = @Word(dm, "^", 1);

fullName = @Word(dm, "^", 2);

dspName = @Word(dm, "^", 3);

if (@Text(colKey) != ""){

colVals = dmData.get(colKey);

if (colVals == null){

dmData.put(colKey, {SN: colKey, DN: dspName, FN: fullName, TotDeals: 0, TotLseRev: 0, TotBgtRev: 0, NewDeals: 0, NewLseRev: 0, NewBgtRev: 0, LTDeals: 0, LTLseRev: 0, LTBgtRev: 0, VACDeals: 0, TotGLA: 0, DeadDeals: 0});

}}}

viewScope.statistics_Ranking_DMData = dmData;  }]]></xp:this.beforePageLoad>

 
2) Within a custom control, I run the following code (looping through a json array) to populate values. Note, I only want to update my code variable (dmData) and not the viewScope variable:

var dmData = viewScope.statistics_Ranking_DMData;

for (i = 0; i < jsonValues.length; i++) {

colKey = jsonValues[i].SRanking_Leasing_Agent_SN;

dspName = jsonValues[i].SRanking_Leasing_Agent_Dsp;

fullName = jsonValues[i].SRanking_Leasing_Agent;

colVals = dmData.get(colKey);

if (colVals == null){

dmData.put(colKey, {SN: colKey, DN: dspName, FN: fullName, TotDeals: 0, TotLseRev: 0, TotBgtRev: 0, NewDeals: 0, NewLseRev: 0, NewBgtRev: 0, LTDeals: 0, LTLseRev: 0, LTBgtRev: 0, VACDeals: 0, TotGLA: 0, DeadDeals: 0});

colVals = dmData.get(colKey);

}

deadDeals = colVals.DeadDeals + jsonValues[i].SRanking_Dead_Deals;

totDeals = colVals.TotDeals + jsonValues[i].SRanking_Total_Deals;

totLseRev = colVals.TotLseRev + jsonValues[i].SRanking_Total_Lse_Rev;

totBgtRev = colVals.TotBgtRev + jsonValues[i].SRanking_Total_Bgt_Rev;

newDeals = colVals.NewDeals + jsonValues[i].SRanking_New_Deals;

newLseRev = colVals.NewLseRev + jsonValues[i].SRanking_New_Lse_Rev;

newBgtRev = colVals.NewBgtRev + jsonValues[i].SRanking_New_Bgt_Rev;

ltDeals = colVals.LTDeals + jsonValues[i].SRanking_LT_Deals;

ltLseRev = colVals.LTLseRev + jsonValues[i].SRanking_LT_Lse_Rev;

ltBgtRev = colVals.LTBgtRev + jsonValues[i].SRanking_LT_Bgt_Rev;

vacDeals = colVals.VACDeals + jsonValues[i].SRanking_VAC_Deals;

totGLA = colVals.TotGLA + jsonValues[i].SRanking_Total_GLA;

dmData.put(colKey, {SN: colKey, DN: dspName, FN: fullName, TotDeals: totDeals, TotLseRev: totLseRev, TotBgtRev: totBgtRev, NewDeals: newDeals, NewLseRev: newLseRev, NewBgtRev: newBgtRev, LTDeals: ltDeals, LTLseRev: ltLseRev, LTBgtRev: ltBgtRev, VACDeals: vacDeals, TotGLA: totGLA, DeadDeals: deadDeals});

}

 
 
3) The issue is that once the code in #2 executes, my viewScope variable has been updated as well. I've found that I can make this change to the first line of code #2 to fix the issue: 

var dmData = viewScope.statistics_Ranking_DMData.clone();

 
However, I'm concerned because I have tons of code where I initialize variables based on viewScope variables so I'm trying to figure out if this is something I've been coding incorrectly all this time (and I need to use the "clone()" on all of them), or is this just a unique situation where this is causing an issue for me. 

Can someone clarify this for me? 

Thanks so much! 

Crista 

Nov 8, 2012 5:12 PM
13 Posts
Re: viewScope variable binding question
P.S. The "DBLookupArray" function is a very nifty function written by Tom Steenbergen. It works much like the standard DBLookup but it's a little nicer. You can find it with a google search. :)
Nov 9, 2012 1:27 AM
129 Posts
Re: viewScope variable binding question
When you bind an object/array to a variable, you pass the reference to the object. 
 
E.g.
viewScope.a = [1,2]; 
var b = viewScope.a; 
b.push( 3 ); 
 
// viewScope.a -> [1,2,3]
// b -> [1,2,3] 
 
 
If you're dealing with boolean, string or number, I believe you're safe. As you discovered, cloning the object is the way to go if you want a shallow copy of the object. You can run into issues with shallow copies (clone) as well if you're copying objects that contain other objects. 
 
More information about shallow/deep copies: 
http://www.jusfortechies.com/java/core-java/deepcopy_and_shallowcopy.php 
Nov 9, 2012 12:21 PM
13 Posts
Re: viewScope variable binding question
Wow, I can't believe I didn't know that. Yikes!
 
Thanks for the clarification and the link to more info. 
 
Cheers!