17

In every Lightning controller you have these outer parentheses wrapping the actual object:

({
    getInput : function(cmp, evt) {
        var myName = cmp.find("name").get("v.value");
        var myText = cmp.find("outName");
        var greet = "Hi, " + myName;
        myText.set("v.value", greet);
    }
})

So okay - this is making it an expression but what's the point? Somebody claimed that this is an IIFE but I don't think so, even though "normal" JavaScript libraries are doing it with an IIFE like this:

({
    ...
})();

Why is it wrapped in parentheses but missing the following parentheses, making it an IIFE? Why is it different to "normal" JavaScript libraries? What am I missing here?

I'm not doing JavaScript all day, so it's probably just something simple that I miss. I hope somebody can explain this.

  • 4
    I've asked Kris Gray if he'd chime in on this. Off the top of my head, there's no particular reason why it's necessary, except that the code you write isn't the code that appears to the browser, since it's compiled into a different format – sfdcfox Jul 30 '18 at 14:18
19

This choice was made for two reasons.

  1. We parse the Controller and Helper on the server to validate them. There are many different Java Parsers of JSON we could use, but regardless which we choose we wanted to be consistent with the client. Which wants Objects wrapped in parentheses JSON.parse("({})") vs JSON.parse("{}").

  2. Some editors will complain that what you're writing is not valid JSON and thus show syntax errors if you do not wrap it in ()

This decision was made many years ago (8ish), but I'm pretty sure #2 was the primary reason.

  • This is odd. Why would a JSON need to be wrapped in parentheses? (Actually this makes the JSON invalid.) And how can you parse something that looks like JavaScript with a JSON parser (since JSON is only a subset of JavaScript)? The above example is valid JavaScript but invalid JSON, so I'm honestly confused by this explanation. – Semmel Jul 31 '18 at 7:25
  • @Semmel comments in JSON aren’t valid either. I know. But eclipse was complaining without the brackets. So in the go. – Kris Gray Jul 31 '18 at 14:18
9

The various parts - controllers, helpers and the XML components themselves - are all assembled into a valid single JavaScript file that represents the component. So the pieces you edit are in a somewhat arbitrary format before that conversion. But it's a pity the JavaScript files are not valid JavaScript and so tools like http://jshint.com complain a bit.

If you use your browser's "Sources" tab in its "Developer Tools" you will be able to see the resulting JavaScript. (There are also libraries that contain common pieces of logic used by multiple framework components.)

(The expected syntax definition can probably be found somewhere in this open source forcedotcom/aura Java code.)

This process is one reason to not be too concerned about the cost of components versus the cost of raw HTML in a component. Both end up as chunks of JSON in the single JavaScript file and so have to be processed to generate corresponding DOM nodes.

  • This is the only sense I could make of it... but it would shed so much light if Salesforce did explain some day lol – Javier García Manzano Jul 30 '18 at 14:23
  • 4
    I've asked Kris Gray to chime in, he usually responds in a few hours. – sfdcfox Jul 30 '18 at 14:24
  • Do you have an example where the JavaScript is not valid JavaScript? – Semmel Jul 31 '18 at 7:25
  • 1
    @Semmel Paste a controller into jshint.com and you get the errors "Expected an assignment or function call and instead saw an expression." and "Missing semicolon.". – Keith C Jul 31 '18 at 8:15
  • Ah. I missed the warnings - thanks for hinting me in the right direction. – Semmel Jul 31 '18 at 14:10
3

This is how I understand it going through the documentation. The Lightning framework Client-Side Controller's documentation mentions as below:

A client-side controller is a JavaScript object in object-literal notation containing a map of name-value pairs. Each name corresponds to a client-side action. Its value is the function code associated with the action. Client-side controllers are surrounded by parentheses and curly braces. Separate action handlers with commas (as you would with any JavaScript map).

So this corresponds to a JS object as specified above. Now if you see the Javascript object's definition here, it mentions as below:

Objects can be initialized using new Object(), Object.create(), or using the literal notation (initializer notation). An object initializer is a comma-delimited list of zero or more pairs of property names and associated values of an object, enclosed in curly braces ({}).

And as for for parenthesis itself, as the documentation mentions that the complete JS is surrounded by paranthesis, I would assume (not completely sure) if that's something that the framework does to group the "controller functions".

  • 3
    Except the () isn't literally needed in plain JavaScript to create an object literal. – sfdcfox Jul 30 '18 at 14:20
  • Agreed. Not completely sure, but that could be possibly to group the actions within the controller itself, something done by the framework itself. As you have already reached out to Kris Gray, so waiting for your inputs here. – Jayant Das Jul 30 '18 at 14:34
  • Well. At least the docs are stating that it has to be that way (surrounded by parentheses) - this is exactly the part that I missed. – Semmel Jul 31 '18 at 7:08
  • 1
    @Semmel And that's where I had mentioned if its done more by the framework (was definitely not sure on that) itself rather than following the complete JS structure. And with Kris' answer, it does look like its a semantic for the platform/framework parsers. – Jayant Das Jul 31 '18 at 12:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.