Geeks With Blogs

News profile for Aligned at Stack Overflow, Q&A for professional and enthusiast programmers

Donate Bitcoins

Check out Elapser from T3rse!
"free in Christ Jesus from the law of sin and death." Romans 8:2 (ESV) Check out the Falling Plates video on YouTube.
more about the Gospel
And then listen to Francis Chan speaking at LifeLight in SD.

Programming and Learning from SD

See John Papa's article for more information on the revealing pattern.

See http://www.addyosmani.com/resources/essentialjsdesignpatterns/book/#revealingmodulepatternjavascript for a great reference as well.

I was trying to expose a property in my JavaScript object and setting it from an outside caller. When I ran the code, the value didn’t change. This held me up for awhile yesterday. When I Googled, GoodSearched the problem today, I found a question on Stackoverflow that was similar and lead me in the right direction. You need a setter, makes sense now ("It's all about scope" as a co-worker put it). So I put together a quick test in my JsFiddle example. Here’s a copy from the example. I also have an example without the initial instantiation and as a Knockout view model in the fiddle.

var bike = (function () {
  var isMoving = false,
    isMovingSetter = function (value) {
      isMoving = value;
    },
    test = function () {
      console.log('The bike is moving? ' + isMoving);
    };
  return {
    IsMoving: isMoving,
    Test: test,
    IsMovingSetter: isMovingSetter
  };
}());

// directly setting the property doesn't change the value, this tripped me up for awhile
bike.IsMoving = true;
console.log(bike.IsMoving);
bike.Test();

// a setter is necessary
bike.IsMovingSetter(true);
bike.Test();

Addendum:

Getters are required as well. This question from SO answers it pretty well.

I created a jsFiddle that shows the problem, then I added the getter and access it that way.

Posted on Tuesday, January 15, 2013 8:31 AM JavaScript | Back to top


Comments on this post: Setting a var property in the JavaScript Revealing Module Pattern requires a setter and a getter

# re: Setting a var property in the JavaScript Revealing Module Pattern requires a setter
Requesting Gravatar...
The code you have written is too much informative and helpful for me. Thanks for sharing it.
Left by Ian Harvey on Jan 21, 2013 2:40 AM

# re: Setting a var property in the JavaScript Revealing Module Pattern requires a setter and a getter
Requesting Gravatar...
I tried using your code and it didn't work the first time. However, I went over it with a fine tooth comb and realised I made a few typo's.

Anyway it works now and is really good. Will leave more feedback once I use it more.

Thanks
Left by Tommy Part on Feb 14, 2013 11:07 AM

# re: Setting a var property in the JavaScript Revealing Module Pattern requires a setter and a getter
Requesting Gravatar...
Actually, the code (as you have published above), would allow directly setting the isMoving property (via the IsMoving property you are returning - gosh that's confusing). There's no technical need for a setter here.

I took the opportunity to clean it up and provide a few additional examples which may explain this pattern (the revealing module pattern) a bit clearly: http://jsfiddle.net/6ZreR/7/
Left by Michael Wales on Jul 28, 2013 5:22 AM

# re: Setting a var property in the JavaScript Revealing Module Pattern requires a setter and a getter
Requesting Gravatar...
@Michael Wales Thanks for the comment! One thing that is different between our examples, is that my return for isMoving is IsMoving: isMoving, where the public property is capitalized (yes that is confusing). Changing it to return { IsMoving: isMoving ... }, I get 'Bike movement is undefined'.

My conclusions is that if I did not change the capitalization (which I was doing from my C# background and as a convention) would let me avoid having to do setters and getters. Does that sound correct?
Left by Kevin on Jul 29, 2013 1:28 PM

# re: Setting a var property in the JavaScript Revealing Module Pattern requires a setter and a getter
Requesting Gravatar...
Hmmm... it really has nothing to do with the capitals, but then everything to do with them at the same time. Yes, JavaScript variables are case-sensitive.

Everything within the return statement is public, therefore IsMoving would be public and it points to the private variable isMoving (preventing you from accessing isMoving from the outer scope).

I've posted an update to my previous jsFiddle - the only thing I changed were the calls to the publicly available isMoving() on lines 11, 15 and 40. Then, I made the same small change on line 24 within the closure, returning the value of isMoving as the property IsMoving.

http://jsfiddle.net/6ZreR/9/

The take-away lesson: these variable names suck. Don't do this ever again.
Left by Michael Wales on Jul 29, 2013 2:26 PM

# re: Setting a var property in the JavaScript Revealing Module Pattern requires a setter and a getter
Requesting Gravatar...
@Michael Wales: Its not the naming that is the problem, it is that IsMoving is a pointer to isMoving only until IsMoving is set from the outside - now it is its own object. isMoving will maintain its private value. This is shown by the fact that your example has to use IsMoving even internally because isMoving does not get changed so isMoving and IsMoving are not equal - so in your code its pointless to have the internal isMoving at all since even internal code can't / isn't using it. The more obvious solution would be to use a javascript property (Object.defineProperty) if you wanted to hide an internal yet set it external - or public functions. Just exposing a public IsMoving gives the impression it can be set and obviously doing so causes issues depending on how the internals are written so I would lean toward a get function and set function if a property was not desired.

Yes this is old, just wanted to shed a little light in case someone stumbles on this looking for help.
Left by Robert on Mar 14, 2014 10:04 AM

Your comment:
 (will show your gravatar)
 


Copyright © Aligned | Powered by: GeeksWithBlogs.net | Join free