Pages

Sunday, October 23, 2016

Lightning Components vs. Visualforce

In my last post, I wrote that "there's a new, alternative style of coding available for building custom reporting/data-entry screens inside Salesforce ("Lightning Components" instead of "Visualforce"). Our web developers don't write either right now, but if they did, they'd be happy to know that the new option is more modern-web-development-ey than the old option.

I've been slowly reading the thick book about Lightning Components that I picked up at Dreamforce.

After getting through chapter 2 ("quick start"), I thought, "I should take an existing Visualforce page I've written and rewrite it in Lightning Components as a programming exercise.


Most Visualforce pages I've written are simply a way of displaying the results of an SOQL query to an end-user, so they weren't going to be very exciting.

The most "interactive" one I've written prompts the user for a date and plugs that into an SOQL query whose results are displayed to the end-user. Some of the fields in the display allow their values to be changed, and there are Save/Cancel buttons for all changes made so far on the page. This seemed like my best candidate for a conversion.


Unfortunately, even this isn't a great candidate for conversion, as far as I can tell. Here's why.

Step 1: Think of everything a user of your VF/LC app "does" to the page as a "browser event."
Here are all of mine:

  • User fills a date in the date-picker box
  • User clicks the "submit chosen date and refresh page with data from server, showing event attendees for that date" button**
  • User fills in an "attendance status" picklist with a given value
  • User clicks the "save changes to server and refresh page with latest data from server" button**
  • User clicks the "discard 'attendance status' picklist-value changes made in browser" button*

Step 2: For each "browser event," ask yourself two questions:

  1. Does it actually make any substantial changes happen, besides what the user expected?
    (If "user clicks a checkbox" is the "browser event", then "checkmark toggles inside checkbox" is NOT a "substantial change," but "text next to checkbox changes color" IS.)
  2. Does the "substantial change" depend upon the Salesforce.com server being contacted?
    ("...saves changes to server..." or "...gets data from server..." DO require the server to be contacted. "...Text next to checkbox changes color..." DOES NOT.)

In my case, the "user fills in" items don't do anything "substantial."

My "substantial changes" (marked with at least 1 asterisk & boldfaced) occur when the user clicks buttons.

Of those 3 "substantial changes," 2 are completely dependent upon the Salesforce.com server being contacted (marked with 2 asterisks).

Only the "discard" button's behavior could be done without contacting the server, if you had been saving "old values" in the browser's memory as the user made changes.
Even there, though, it's probably much simpler to just ask the server to provide clean data.


From what I can tell so far, Lightning Components makes "substantial changes that don't have to talk to the Salesforce.com server" easier to write.

However, "substantial changes have to talk to the Salesforce.com server" involve writing way more code in Lightning Components than they require in Visualforce.


Although it has a few "sections" to it, not all of which are always visible, overall, my page is merely a single "editable SOQL query" user-interface with a few extra controls.

More importantly, I want it to behave "synchronously" with the server.
That is, once a user has clicked a button, I don't want them messing around with the clickable parts of the page until the data-refresh from the server is complete. I want them to lose any work they try to do between button-click and page-refresh.

I have never written a Visualforce page that includes any "substantial" results of users' "browser events" (e.g. button-clicks) that are easily handled entirely inside their browser with JavaScript (e.g. "change the color of the text").

Therefore, from what I can tell, my conversion will inherently involve a lot more code in Lightning Components than it involves in Visualforce.
(And more memory usage in the user's browser.)
Please correct me if I'm wrong!


Visualforce has a very efficient one-line syntax for communicating with the Salesforce.com server and refreshing the Visualforce page in response.

Lightning Components, from what I can tell (please correct me if I'm wrong!), makes you:

  • Code a browser-event handler to fire LC-event-#1
  • Code a LC-event-#1 handler to talk to the server and to fire LC-event-#2 upon response
  • Register a listener for LC-event-#2
  • Code a LC-event-#2 handler to refresh the page with data returned from the server

I still plan to do the conversion as practice, but I wonder if there's a way to get the best of both worlds for my apps: Lightning-Components-looking responsive styling coded in a minimal amount of Visualforce.

Wednesday, October 12, 2016

Dreamforce 2016 Lessons Learned

Lucky me, I got to attend Dreamforce. I had colleagues going to plain-English "what you can do with Salesforce" talks, so I filled my days with "how to program Salesforce" lessons. Here's a summary of what I learned.

(Also, I plan to put out a "how to install WinPython on Windows" walk-through but haven't had time to capture screenshots of the version I found that works well without administrator rights. It'll happen, though!)

  1. I got to go to a "gripe to the people who maintain Salesforce" session and gripe about certain "relational databases have been doing this for decades--why doesn't Salesforce?" things (e.g. the fact that data-cleansing "trigger" code can't be written against certain data tables in Salesforce). I learned some interesting history about why such things are broken. (For the triggers, the fact that the tables having data in them had about a 3-year head start on triggers existing at all. Which means you have to rebuild the tables or something, and apparently that's expensive in Salesforce-employee-time for not-many-customers, lots-of-rows tables, so money to pay someone to do it has to be budgeted from the top at Salesforce.) Ultimately, as I suspected, the almighty dollar is an issue. Fixing such basic functionality doesn't easily compete with adding other features that are better at bringing in new multi-million-dollar contracts to Salesforce, so the problem gets picked at slowly as limited budgets allow. But it was fun to get to tell someone whose job it is to fix these issues how annoying these issues are to his face and get sympathetically nodded to!
  2. Salesforce is pushing a new "artificial intelligence" product they just acquired pretty hard, but it seems to me that it's for companies whose business models mean they can be "fuzzy" about how they handle customer data. (One of the brag-stories was something along the lines of, "We didn't like our 'unsubscribe rate,' so we used AI to predict who was likely to unsubscribe and to preemptively unsubscribe them!") That said, I didn't actually go to any sessions about Einstein - it just had a display in the way of my coding classes. A marketing colleague was way more interested (e.g. mining Facebook/LinkedIn data).
  3. There's a new, alternative style of coding available for building custom reporting/data-entry screens inside Salesforce ("Lightning Components" instead of "Visualforce"). Our web developers don't write either right now, but if they did, they'd be happy to know that the new option is more modern-web-development-ey than the old option.
  4. There's an option to turn on a new look & feel for the user interface in Salesforce ("Lightning Experience"). It's been pretty hideous (a bunch of icons instead of words), but it's getting better (they brought the words back). Not sure if it's worth the work. The new & old user-interfaces have different features + some overlap, so it's not just flipping a switch. I learned some ways to find out what's around & what isn't + to preview what our org would look like in Lightning Experience. Overall, I think our users tend to want to be able to see lots of data at a time, and font sizes and whitespace seem smaller in the "Classic" UI, so I think "Classic" is better for us.
  5. I learned some things I can do to make sure that my administrator rights for a web application I have hosted externally are secure (e.g. lock down my admin account with two-factor authentication).
  6. I thought I was writing one type of test ("unit tests") against code I was writing in Salesforce, but it turns out it's actually closer to another ("integration tests"). Probably OK because "integration tests" tend to be closer to answering the question, "does this do what the end-user asked for?" Not sure if writing true "unit tests" is actually necessary for what I'm writing, but good to know the difference and some new things to learn ("mocking") if I ever want to do so.
  7. I learned some code necessary to ensure that code I write in Salesforce respects normal user-access settings (it goes beyond "with sharing"). That said, most of what I've written purposely "plays God" & takes care of stuff a user can't. But perhaps some of it doesn't have to "play God," so this is a nice tool to have in my toolbelt. I learned it last year but went for a refresher this year and plan to start using it more.
  8. Database triggers (code that executes when people save data in Salesforce) can make "asynchronous" calls to external services that take a while to return results (e.g. "Hey Google, what's the driving time between these two addresses?"). However, you want to make sure you write such code only for database-data-change conditions that are likely not to happen too often (e.g. less than 20 times per 10 minutes, or less than a few hundred times per day), because only 50 such calls can stack up in Salesforce at a time, and the 51st+ just kind of fail, possibly irrecoverably).
  9. I learned that, with Apex, I can write my own REST API that interacts with my Salesforce org, rather than relying on the Salesforce REST API. This can potentially let me reduce the number of "API calls" I have to make when, say, interacting with my Salesforce org from Python running on my hard drive. Potentially. Doesn't yet pass the XKCD automation test for my work.