FORUM PLAN UPDATE
Date revision: This forum will remain open to new posts and responses until December 1, 2018. (After that date, you will still be able to view and search the forum.) Also, we're taking a second look at the best place to host future conversation. For now, keep using this forum, and stay tuned for more news.



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!

FORUM PLAN UPDATE
Date revision: This forum will remain open to new posts and responses until December 1, 2018. (After that date, you will still be able to view and search the forum.) Also, we're taking a second look at the best place to host future conversation. For now, keep using this forum, and stay tuned for more news.