Timeout

To the few precious readers that I manage to attract to my blog, I want to apologize for missing a couple of weeks. There was a user group meeting, and then a trailhead workshop, (locusts, a terrible flood, I wasn’t my fault I swear to Gooooooooooood!!!) that I had to prep for so I missed a couple entries. It’s all for the good though because interest in the Logic Through Formulas has sort of stalled out and to be honest, I’m lacking ideas for content. Therefore, I’m taking a timeout on that series but it will still be here for any admins that may want to see a “formula in code” if they think it will help them learn something more. So if you’re out there, don’t hesitate to send me something :)

So in case you missed it, our Wisconsin based “Women in Tech” group sponsored a Trailhead Workshop in Lake Mills, WI over the weekend and was a great success. (Though we ARE still waiting for a number the feedback surveys). We plan to do more, so follow myself or either of these two fine folks on Twitter: Jenny Bennett & Kelly Leslie, in order to get the latest news on the next workshop. We also had the great pleasure to welcome Chris Duarte to the midwest. She made it through her weekend without freezing, so that’s a plus ;)

For a recap: see ChattyAdmin’s blog (ignore the googy-ass face I was making…we were all supposed to be, but I don’t think anyone else knew, but I DISTINCTLY heard someone say “make a funny face”)

Apex Logic Through Formulas: Part 3

I’ve had to reach into my own bag of formulas to find an example for this week’s entry. Last week I was focused on our local user group so we didn’t have an entry, this week I’d like to make up for that a little bit. This week’s formula is a bit more involved but nothing crazy:

formulas3-1

Let’s walk through what the formula does:
First we have an AND function wrapped around everything. If we think of the AND function as this box that we just put things into and shake up and look inside our AND box will contain a value of either TRUE or FALSE. If everything we threw inside our AND box is TRUE, then our overall value should be TRUE. If even one item in our AND box is FALSE, the whole thing is FALSE. The trick here is that our AND box contains another BOX that can have its own items inside. This inner box is an OR box and in this case only one of the items inside needs to be TRUE in order for the whole BOX to be TRUE.

So the first item we put in our AND box is checking a Boolean field on our object. This is a checkbox that is basically telling us that this “item” is external. (Let’s ignore the business case for now as its irrelevant, just know that this is a checkbox that will either be check or unchecked. Since a Boolean value is by default either TRUE or FALSE we don’t need to do any sort of comparisons, here. However we did wrap this in a NOT function. So, if our External Item checkbox is indeed checked, (therefore TRUE) our NOT box is reading NOT(TRUE). So basically if our checkbox is checked, this would return FALSE thereby making our entire AND box false. Clear as mud? We’ll try to clear that up when we have an actual example, but for now lets check the next part.

Lines 3 through 7 contain our OR box. We are checking to see if our Opportunity is either in a stage of VALUE1, VALUE2, or VALUE3. (The stages have been changed to something generic as this is an actual formula in an org and I’m not comfortable giving away too much information). So if our Opportunity is set to any of those three stages, our entire OR box will be TRUE. Incidentally if we only had four stages, this OR box could have been removed and we simply could have said inside our AND box: “NOT(ISPICKVAL(StageName, ‘VALUE4’))” meaning if it isn’t VALUE4 than it must be one of the other values, but I digress.

Lastly we are checking a multi-picklist field (ssshhhh don’t tell @SteveMoForce) to see if one of the selected values is ‘APPLICATION’ and if so, then that part will also be TRUE.

Lets walk through an example before we get into code. Lets say we have the following Opportunity information:

External Item: unchecked
StageName: VALUE2
Item Key: SERVICE and APPLICATION are selected

This formula would return TRUE on line 2: NOT(External_Item__c) which is saying NOT(TRUE). If something isn’t TRUE than it must be FALSE. So we are checking to see if External_Item__c is FALSE (unchecked) which it is indeed unchecked, so the result of our NOT box is TRUE, since External Item is not TRUE (checked). (I know its still mud…but you’ll get it).

For our OR box, we are NOT in StageName ‘VALUE1’ but we are in StageName ‘VALUE2’ — so since one of our items in our OR box is true, the whole OR box is TRUE.

Lastly, our Item Key indeed contains the text ‘APPLICATION’ so that too is TRUE. So basically our big AND box that wraps this whole thing contains:

AND(
    TRUE,
    TRUE,
    TRUE
)

So everything in our AND box is TRUE and therefore our whole box is TRUE and this rule would fire. Its reminiscent of “solving for X” using substitution back in our Algebra days, (and you thought you’d never USE that stuff).

Now let’s code this puppy. Again let’s assume that I’ve done the proper querying of my Opportunity and included the fields that I am interested in. As we did back in lesson 1, we are going with a very verbose solution. This could be written in so many different ways and the idea here is to help you simply tie the logic together. We’ll refactor it, but lets start with using perhaps some nested IF statements (again, this code won’t compile on it own):

formulas3-2

Line 1:
This is just our function declaration. Let’s not worry too much here at the moment as the logic is within the braces.

Line2: We are checking to see if the External Item is NOT True (unchecked). This matches our formula’s use of the NOT() function. We could have also written it like this:

if(myOpportunity.External_Item__c == False) {...}

…but that wouldn’t have really matched what our formula was saying. It would have been equal, but not “equivalent” ;)

Line 3:
Using our Opportunity example from above, that would pass and we would fall into our next IF statement on line 3. Here we are checking the Opportunity’s StageName to see if its either ‘VALUE1’, ‘VALUE2’, or ‘VALUE3’. The || symbol in our if statement means “OR” and follows the same rules as the OR box in our formulas. If any of those comparisons are True, then the whole thing passes through to the next line.

Line 4:
Here we are checking to see if our multi-picklist field as APPLICATION for one of its selected values. In Apex, you can use the “contains” function to look into some text to see if a given sequence of letters or numbers are present. Also, a multi-picklist field’s selected values in apex appear as one long string with each selected item separated by a semi colon. So our example would have: ‘SERVICE;APPLICATION’ as the value for that field. PLEASE NOTE: this code as written could wind up in a bug because if for some reason your multi-picklist had both ‘APPLICATION’ and ‘APPLICATION LICENSE’ as viable selections, and someone chose the latter, our code on line 4 would still find the word “APPLICATION” in our selection even though it was part of the “APPLICATION LICENSE” selection. So there is a better way to do that by splitting up the selections into a list and looking for the value that way, but that lies beyond the scope and I don’t want to dive too deeply too soon.

Upon passing line 4 successfully, we return a value of True in our function and we are done. If at any point we don’t pass the if statements, we fall out and wind up on line 9 where we return false.

As stated there are many other ways to write this:

formulas3-3

or

formulas4-3

but my point is to get you to focus on the similarities of the logic between Apex and Formulas. We can worry about writing more concise code once you get more comfortable with the concepts. Your homework? Yes there is homework. Given the following Opportunity, will it pass our tests or fail them? If it fails, where will it fail?

External Item: checked
StageName: VALUE3
Item Key: 'SERVICE' and 'APPLICATION' are selected

or

External Item: unchecked
StageName: VALUE4
Item Key: 'SERVICE'

I hope this helps you along your path. As always, I am open to suggestion and send me those formulas!

:wq!

Apex Logic Through Formulas: Part 2

Last week we dove right in with a formula from SteveMo. This week, I want to take a small step back and rather than just transform a formula into Apex, I’d like to talk on a more general level. Often times our formulas are checking for equality between two fields, or one field and some expected value. There are numerous ways to do this in formulas, but I wanted to show you some ways that you can check for equality in Apex as well.

Lets start off with with something simple, like checking if the value of a picklist is equal to some known value. In a formula one would have:

ISPICKVAL(MyField__c, 'Some Value')

In apex however, we don’t need the “ISPICKVAL” and we use the double equals to check for equality as such:

MyObject.MyField__c == 'Some Value'

The above is usually put within an if statement or its result assigned to a variable like this:

if(MyObject.MyField__c == 'Some Value') {
    //do geek things here
}

–or–

myBooleanVariable = (MyObject.MyField__c == 'Some Value')

Now lets talk about checking for inequality. Normally this is wrapped in a NOT function within a formula like so:

NOT(ISPICKVAL(MyField__c, 'Some Value'))

In apex we check for not equals usually using the not equal operator (!=):

MyObject.MyField__c != 'Some Value'

Again we put this in if statements or assign to variables as shown above. There are also the >,<, and <> operators but these function identically in apex as they do in formulas:

Some_Value > 0
Some_Value < 0
Some_Value <> 'some other value'

For some the ‘<>‘ operator may be new, its another way of checking for inequality and I prefer to use that method in formulas but use the != notation in apex. I’m not sure why I prefer it that way other than that’s just what I’ve been using in other languages since I started programming and that’s a 15 year habit that I don’t see me breaking anytime soon.

I apologize if this week’s lesson feels a bit light, but you can help with that. Send me your formulas! :)

Until next time

:wq!

Apex Logic Through Formulas: Part 1

Last week I mentioned that I would be starting a new series of sorts. Today will be the first entry in that series. My hope is to bridge the gap between point and click development, and slinging code for those admins/developers that are hesitant to make “the leap of faith” into the world of of development. As mentioned, fellow MVP @SteveMoForce had mentioned that perhaps seeing a formula of sorts (be it from a validation rule, workflow entry criteria, etc) written out to its equivalent in Apex would be of use to begin understanding it.

While writing this stuff likely isn’t going to be useful to you directly, the intent is that since — as an admin — you are already familiar with how formulas work and how to write them that it isn’t as far a stretch to go from the logic of formulas to the logic of slinging code. After all, that is the biggest hurdle when learning to code, the logic. The rest is just syntax, like learning a new language, and for you the admin, more like learning the nuances of a given dialect of a language.

So for our first example, SteveMo was kind enough to donate the following formula that simply looks at four fields, determines if there is a value in any of them and if there is a value in more than one, return true. I’m told this was part of a validation rule the expects that “any” of the fields can be filled out, but only one of them can contain data at any given time:

IF(ISBLANK(Field_A), 0, 1) +
IF(ISBLANK(Field_B), 0, 1) +
IF(ISBLANK(Field_C), 0, 1) +
IF(ISBLANK(Field_D), 0, 1) > 1 

What we have in this formula is a few “IF” functions, some math operations, and a comparison. (Comparisons always return true or false, since a Validation rule fires when its criteria is true, we need a comparison at the end of the day). Before jumping into the coding portion, lets ensure we all understand this formula.

IF(ISBLANK(Field_X), 0, 1):
When you use an IF function in a formula, it checks to find out if a given condition is true. Upon finding it is true it returns the next value in the “IF box”, if its false it returns the last value in the IF. So in this case we are checking to see if the value of the given field (Field_A) is blank. If it is indeed blank (condition is true) then the “value” in our IF box is 0, if it is not blank, the value of our IF box is 1.

We Do Math:
We take the results of these IFs and add them together, if they are all blank we get 0 + 0 + 0 + 0 = 0. If only one of the fields is filled out (it doesn’t matter which), we could get 0 + 0 + 1 + 0 = 1. Lastly if more than one field is filled out (again any combination) we could end up with 1 + 0 + 1 + 1 = 3.

Now we compare:
Finally we will look at the result of our math and check to see if it is greater than 1. If it is greater than one, our Validation Rule becomes TRUE and will fire a message. If it equals or is less than one, our Validation Rule is FALSE and all is well.

So let’s write some Apex:
I know your excited, but I want to clear a few things up. Firstly, we have to imagine for now that we have done some other coding to get access to this object’s fields. Following Steve’s example lets say we have a Widget object with the following four fields: Field_A__c, Field_B__c, Field_C__c and Field_D__c. Furthermore, as it is out of scope for this series, lets assume we’ve written the necessary code to allow us to refer these fields as “MyObject.Field_A__c” etc. Secondly, this code will be very verbose. There will likely be more concise/better ways to write this, but we have to walk before we run. Lastly, I may use words like variable or other “coding words” — I will try to explain those as I go, but remember the concept here is to map what you know of formulas to something you are unfamiliar with so that your mind can begin to marry the two together. This is largely an experiment so whether this helps remains to be seen. Stay with me.

Lets look at the code (I put the code in an image for two reasons. First, so that I get nice line numbers with my code and its easier to do a walkthrough. Second, so that if you wanted to play with this, you’d have to type it in manually. I know, I’m a jerk but cutting and pasting is one thing, but I believe it helps you absorb it all if you type it in as you go. That being said, this won’t compile directly in eclipse or sublime — remember that we are assuming I’ve done some other stuff, but perhaps some of the more enthusiastic amongst you might read up on that “other stuff” and I don’t want you mad at me when it doesn’t compile):

formulasinapex1

Now lemme ‘splain:
Line 1: Don’t get hung-up here. This is how we write a chunk of code that we can refer to later from some other place. Its called a function and we write code that “calls” it, which basically means, do the stuff in between my curly braces ({…}). For now just consider line 1 and line 33 as the walls of the container in which we are holding our apex version of the validation rule. The “black box” of magic so to speak.

Lines 2-4: Here we are telling the compiler (the bit that checks to make sure our code is valid and will run) that we are going to use some variables to hold integer values (whole numbers, not decimals, not text). Variables are placeholders for items we want to refer back to later, or do something with. In our case, we will be putting a value of either 0 or 1 in each of these based on whether or not our fields have a value in them and adding them up later.

Line 5: Here we are telling the compiler about another variable, but instead of holding a number it will hold a Boolean value which simply put, means its going to hold a value of TRUE or FALSE.

Line 7-11:
This might look familiar, its an IF statement quite similar to the IF function used in our formula. There is a certain syntax wrapped around us here so now would be a good time to point that out. An IF statement in Apex has a condition that you are checking for in parenthesis (in this scenario, the code in between the parenthesis is similar to the ISBLANK portions of our Validation Rule criteria), and then some curly braces. The curly braces separate the logic for us a bit. The code in between the first set of curly braces are evaluated when the condition in parenthesis is true. An if statement may also have more sets of curly braces. In our case we have an “else {…}” block. THIS block gets evaluated when our condition is not true (and therefore false, get it?). At some point in the future we can talk about the “else if {…}” block which allows us to check for numerous conditions by stringing them together, until one of the conditions finally winds up true or we run into an else block, or just run out of conditions to check all together.

So continuing with line 7-11, on line 7 we are checking our condition: if(myObject.Field_A__c == null). What is null you ask? Null is essentially “nothing” — so we are checking to see if there is any value there or not. The check for equality in Apex is the double equal sign “==” so this bit is equivalent to our ISBLANK function in our formula. If there is no value in myObject.Field_A__c then our condition is true and line 8 will get evaluated. On line 8 we store a value of 0 in our Integer variable called “a” — if there was indeed a value in myObject.Field_A__c then our condition would be false and therefore our “else {…}” block would get evaluated and the code on line 10 would tell our Integer variable “a” to hold onto the value of 1.

Lines 13-32: We repeat this logic for all four fields either storing 0 or 1 in each of our variables. When we are done we should have four variables that we can then add the values they hold together like we do on line 31. But that line looks just a bit different doesn’t it? Here we are saying “Hey compiler, remember that Boolean variable I told you about? Well take the value of adding a + b + c + d (my picture left out the + d — sorry) and compare that to see if its greater than 1 and store that result in my isGreater variable.” That may be a bit much to grasp, and I get it. Here’s what is happening. We are adding (a + b + c + d) but much like the order of operations from elementary school, we want that math to happen before we compare it to 1. We could have written it like so:

Integer i = a + b + c + d;
isGreater = i > 1;

But we can put this all on one line. Remember whenever we do a comparison, we either get a TRUE or FALSE value and Boolean variables know how to hold on TRUE or FALSE values.

Lastly, we “return” the result of our comparison to whatever called it (again elsewhere in code). Our validation rule doesn’t have the concept of a “return value” per se — it just IS that result. (Essentially, technically it does “return a value” but you as the admin are shielded from all of that).

Now some of you out there are saying, “WOW that’s quite a bit of code when my formula was only 4 lines long!” and you’d be right, but formulas have some built in magic that hide some of that extra “stuff” from you. Also, remember I said there may be better ways of doing things? Not all code would have to be that long. This next snippet — don’t worry if you don’t get it, its only here for an example and to show you that not all code is so drawn out — would do essentially the same thing:

formulasinapex1a

That above snippet has some more advanced things in them like looping over a list of items, etc. Perhaps we will eventually get there with this series. I’m not sure if we will have Part 2 next week — hopefully so, but it depends on an submissions I may get from readers, or perhaps SteveMo has some more gems hiding somewhere. So feel free to send me your ideas and keep this going. Let me know if you have questions or if I can help clarify anything else in this lesson.

:wq!

Is It Dreamforce Yet

For many of us, our year seems to be measured by the number of days in-between Dreamforce conferences. We wait with anticipation for the release of the band name for the gala, the keynote speakers, the agenda builder, and everything else that comes with Dreamforce. For me, I enjoy all of that just as much as the next person, but Dreamforce — while exhausting — provides me with some relief, a reset button if you will.

With that in mind, I give you my latest creation “Is It Dreamforce Yet”:

‘Nuff said…

:wq!

My DF15 Top Ten People To Meet

…also known as “The I am completely ill-prepared for this week’s post and need to write something” edition.

Everybody does it. As we get closer to Dreamforce people start dropping their “to do” lists, and “things you should check out while at Dreamforce” lists, etc. Among these lists one can normally find someones list of people that they’d like to meet at Dreamforce and if possible, nab a selfie.

Some of these aren’t at all likely to happen, but I’m putting them down here so the universe knows (not in any order…well maybe the first three):

  1. Marc Benioff (and his Benioffs Shoes) — who doesn’t right? I mean, let’s don’t get stupid. Of course he’s on the list!
  2. Parker Harris — now I actually met and chatted with him a bit at the MVP Summit in May, but I missed the selfie opportunity. I don’t want to miss that again.
  3. Shawna Wolverton — I don’t know how I missed her at the summit, but I did…I can’t do that again.
  4. Nana Gregg — I missed meeting her last year at Dreamforce, but have been following her on twitter ever since. Besides we need “Custom Junction” music to hash out ;)
  5. Jenny Bamber — I helped her with some formulas. Been following her blog posts as well. It won’t be long and I think she’ll wind up an MVP and then be too busy so gotta do it now.
  6. Francis Pindar — Somehow miss him at the Summit as well. Jeeeeeeez what was I doing there anyway?!? Plus his twitter handle is “radnip” that’s gotta count for something.
  7. Jeff Douglas — Mr. Lightning himself. No brainer, gotta find him.
  8. Greg Wester — If he’s gonna be there, that’d be awesome. I love his tweets…and if he’s not gonna be there…why the hell not??
  9. Abhi Tripathi — One of the first “random strangers” to reach out to me when I was named MVP. Been wanting to meet up with him ever since
  10. Any one of my twitter followers, readers, listeners, & supporters, etc. So looking forward to making new connections beyond the digital realm!
  11. So there you have it. I plan to meet many more but these are just off the top of my head. It’s also an exercise for me to reach out to people which is something I’m not very good at, but getting better.

    So, if you’re not too shy like I am was…lets chat! Who is on your list?

    :wq!

Knockin’ On Kevin’s Door

Often times, even I don’t have all the answers…I know “shocking” right? In those times of need, we all need that one person we can go to, for me that person is @Kevin Swiggum (my boss at Radial Web, Inc.). I’m sure coming to my rescue can get pretty annoying at times, but he’s been doing this 4 times as long as I have and has seen numerous anomalies in numerous orgs.

For those that do not know, Kevin is a former MVP — and more than likely still would be, but running a business tends get in the way of keeping up with some of those requirements. (Not to mention, I’m working for him and I can keep anyone on their toes…)

So if you don’t already have your “Kevin” — find one, and this goes out to all of the “Kevin’s” out there…thanks for all your help!


Knockin’ On Kevin’s Door

P.S. I don’t normally perform the parodies I write. I have assisted writing a few Salesforce parodies over the past year or so, but since this one is really about my boss, I figured I’d have to own this one D.C al Coda.

P.P.S: for those that are interested, this was recorded on an iPhone 6 with a Voyage Air Travel guitar, on my deck…

:wq!

Streams of Lightning: Part Four

Last week we updated our app to show all of the Poll Question Options as buttons within our parent Poll Question Component. However, it still “does nothing.” What we really need to do is get it to interact somehow, and we will do this by supplying our buttons with a function to call in order to cast our vote.

The first thing we need to do is setup a javascript controller (client side controller) for our Poll Question Item component to talk to. On it we will create a function called “voteItUp” that will in turn call a method on our apex controller that will actually increment the vote count and save our answer.

Open up your PollQuestionItem component in the developer console and in the right-hand side menu, click “Controller” and paste this into the code:

({   
    voteItUp : function(component, event, helper) {
        var optionId = component.get("v.pollOptionId");
        var voteAction = component.get("c.incrementVote");
        voteAction.setParams({ optionId : optionId });
        
        voteAction.setCallback(this, function(response) {
           var state = response.getState();
            if(state === "SUCCESS") {
                document.getElementById(optionId).innerHTML = response.getReturnValue();
            }
        });
        
        $A.enqueueAction(voteAction);
	}
})

What this does is gives us a function that we will use when our button is clicked. In order to determine which button is clicked we will store the option ID of the component that it came from (v.pollOPtionId) in a variable called “optionId.” If you recall we are looping over this component in our parent component and passing it a Poll Option object each time. We then setup the action (the call to the apex method) by looking at our component and finding its declared controller, and telling it to call the “incrementVote” method on that controller. Our apex controller needs to know what option we are voting on so we will have pass in the option ID. This is done with the setParams function and takes a key value pair collection of arguments (voteAction.setParams({ optionId : optionId }) ). We then tell this action what to do when it completes by setting up the callback function. This will run after our callout to apex completes. We’ll then inspect the results and if successful, update the UI.

Please Note: This code is still under some development as I was having some issues locating the output for my vote count. However, this was happening while simultaneously trying to troubleshoot some streaming API issues (coming in part 5). In order to get things to work, I had to resort to using document.getElementById to locate the element in my component to update it. However, that’s also the beauty of this — while its probably not the “blessed” way to do something, while coding you can always “fall back” to tricks like this because your UI, at the end of the day, is still simply HTML and javascript. I would like to come back at some point and fix this, but haven’t found the time :( #StoryOfMyLife

Next we will create the apex controller that our component’s client side controller will call. Simply create a controller using your favorite editor (dev console, sublime, eclipse etc). I called mine PollOptionController. Use the following code:

public class PollOptionController {
	    
    @AuraEnabled
    public static Integer incrementVote(String optionId) {
        Poll_Option__c option = [SELECT Id
                                , Vote_Count__c 
                                FROM Poll_Option__c 
                                WHERE ID = :optionId];
        option.Vote_Count__c += 1;
        update option;
        return option.Vote_Count__c.intValue();
    }
}

Here we take the optionId that we passed in from our client side controller and lookup our custom object by its Id. We then increment its vote count by 1, update it and return the vote count back to our calling function. This will get processed in the “callback” of our action and update our component’s UI with the latest vote count.

Lastly we need to tell our button what function to call when pressed and tell our component which apex controller it needs to be associated with like so:

<aura:component controller="PollOptionController">

    <aura:attribute name="pollOption" type="Poll_Option__c"/>
    <aura:attribute name="pollOptionId" type="String" default="{!v.pollOption.Id}"/>
    
    
    <div style="border:1px solid black;margin:5px;padding:10px;text-align:center;border-radius:5px">
        <ui:button aura:id="voteButton" label="{!v.pollOption.Option_Name__c}" press="{!c.voteItUp}"/>
        <div style="float:right" class="findme" id="{!v.pollOption.Id}">
            {!v.pollOption.Vote_Count__c}
        </div>
        <br/>
    </div>

</aura:component>

We tell our component which apex controller it will be working with by adding the controller attribute to our component declaration: controller=”PollOptionController” and finally we add the “press” attribute to our button to tell it which function to call when its tapped/clicked, etc. One point that may be confusing for some is the use of multiple controllers. Our UI components do not call our apex directly, instead they call our client side controllers (the javascript ones). That is the {!c.voteItUp} notation. However we do tell our component which apex controller it is associated with using the controller attribute in our declaration. So when I say our component is calling a controller function using c.something, I’m making reference to our client side controller, not our apex controller. (For me, it really feels as if the only reason our component mentions the apex controller is so that our client side controller has a place to look up which controller to call a given function on, I could be wrong and it may provide other functionality, but at the moment that bit is unclear to me).

If we load up our application in Salesforce 1, we should now be able to tap the buttons and vote. As you vote you will see the vote count increase. These results are also being persisted to your org as well. We now have a functional lightning app!

I was imagining a use for such an app, and perhaps rather than a “voting” type of application, similar apps could be used on shop floors, in retail etc to reflect an up to date view of inventory. But even better, what if we could stream those results so that users of the app could see an ongoing real-time view of data. For that, we will need some extra javascript libraries, some calls the the streaming API….and another blog entry. Until then…

:wq!

Streams of Lightning: Part Three

As you may or may not know, I was out in San Francisco last week attending my first MVP Summit. For this reason, I did not post part three of my current lightning tutorial. <sarcasm>Since you’re no doubt waiting directly on the edge of your seat<sarcasm>, lets get right back to it.

Last week we left off with a component that was just a tiny bit more flexible than a simple “Hello World” type of component. We were able to add our component to the lightning app builder and configure said component to display the current active poll question. Today we will move on to having this component nest a secondary component that will be responsible for displaying our poll’s options as buttons on the screen. For this, we need to create a brand new custom component, so we’ll begin there.

In the developer console click File->New->Lightning Component. We will call this component “PollItemOption.” Once again we will get the familiar skeleton code, but we’re going to replace it with the following:

<aura:component >

    <aura:attribute name="pollOption" type="Poll_Option__c"/>
    <aura:attribute name="pollOptionId" type="String" default="{!v.pollOption.Id}"/>
    
    <div style="border:1px solid black;margin:5px;padding:10px;text-align:center;border-radius:5px">
        <ui:button aura:id="voteButton" label="{!v.pollOption.Name}" />
        <div style="float:right" class="findme" id="{!v.pollOption.Id}">
            {!v.pollOption.Vote_Count__c}
        </div>
        <br/>
    </div>

</aura:component>

For this component, we are creating a place holder for the Poll Option object itself (pollOption attribute). Remember that we will be using this component “inside” of our Poll Question component that we’ve been working with. That parent component will be passing a Poll Option object to this one. In our case, the Poll Question component will loop over the Options that belong to it and pass them to this component for rendering. We will also likely need the ID of the Option we are working with for updates, etc so we’ll create a place to store that ID as well (pollOptionId attribute).

Next we add some HTML and styling to our component. We will be displaying the poll options as clickable buttons that our users will tap in order to vote for them. I’m wrapping these ui:button pieces in an HTML div for more control over styling. (Once again, I must point out that I am doing this “wrong” during development as style should go in the CSS file that belongs to the component — we’ll get there, but when I’m coding, I like my styles right where I’m working, its just a preference for me). Inside that div we have an instance of ui:button, the label of that button will be the Poll Option’s name field, referred to with our shorthand for accessing attributes in our view: {!v.pollOption.Name}. We can also tell that button what function to call when it is pressed (but we will do that in part 4 next week).

I follow this button up with some HTML markup to assist in styling and then I close it up.

This component, though it will have zero/broken functionality can now be rendered within our parent component, so lets just wire it up briefly so we can track our progress. Open up the Poll Question component that we created in part one. (If you don’t already have it open you will need to go to File->Open Lightning Resources and expand the appropriate folder, highlight the individual pieces and click on the Open Selected button at the bottom of that dialog window).

Now let’s add an iteration over our Poll Options from within our PollQuestion component and have it pass each option to our newest component. Replace the PollQuestion component code with this code (really you only need to add the aura:iteration tag and its contents):

<aura:component implements="flexipage:availableForAllPageTypes"  controller="PollController" >

    <aura:attribute name="pollQuestion" type="Poll_Question__c"/>
    <aura:attribute name="options" type="Poll_Option__c[]"/>
    <aura:attribute name="title" type="String" />
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />

    <h1 style="text-align:center">{!v.title}</h1>
    <p style="padding:10px;">{!v.pollQuestion.Name}</p>
    <aura:iteration var="option" items="{!v.pollQuestion.Poll_Options__r}">
        <c:PollItemOption pollOption="{!option}" />
    </aura:iteration>

</aura:component>

What we’ve added here is the bit called an aura:iteration. It’s how we loop over collections inside lightning components. You specify the variable that you will be using for each iteration and the items over which to be iterated. In this case our variable is called “option” and our items are our poll options that we retrieve from the pollQuestion (!v.pollQuestion.Poll_Options__r} — we retrieved them in our PollController). Secondly, inside of this iteration we are telling this component to use our PollItemOption component that we just created to render each poll option (<c:PollItemOption pollOption=”{!option}” />). Here the “c:PollItemOption” means we are loading a component called “PollItemOption.” That component also has an attribute called “pollOption” that is expecting a Poll_Option object. So we pass our “option” variable in using pollOption=”{!option}”

If you load up your lightning app in Salesforce1 now, you should see our Current Poll application displaying the question and each option rendered as a button. If you’re following along, from last week we should see something similar to the screenshot below. (NOTE: Your titles will be different since I am re-writing my original app for the blog to help me keep track, and you likely won’t have any vote numbers showing up since we’ve not voted for anything yet):

Screen Shot 2015-05-19 at 9.53.08 PM

Things are starting to look a tad more useful. Next week we will add the necessary logic to allow voting on each item, followed by adding in some functionality to wire in the streaming api so that you can watch the votes increase as users vote.

If you happen to be in the Milwaukee area on Thursday, May 21st (I know its short notice) I will be demoing this application complete with streaming at the Wisconsin User Group meeting at: 250 E Juneau Ave Milwaukee, WI. The meeting starts at 11:30am. Stop on by if you find the time.

:wq!

 

Trailhead Lightning Module is a Major Charge!

If you haven’t heard about Salesforce Trailhead by now, allow me to help you out from underneath that rock (I kid because I care).

Salesforce Trailhead was launched at Dreamforce ’14 and if you haven’t tried it out yet, its incredibly cool. I’ve been in a number of different communities and aside from Python/Django (who gets an A for effort), nobody has such a great intro to a platform. Salesforce Trailhead is heads and tails above any “tutorial” for a learning a platform anywhere.  Its professionally put together, it quizzes you on what you’ve learned, it connects to your development org (it helps you set that up too) and keeps track of your progress, and actually rewards your progress along the way with fancy badges.

You can start at the beginning and work your way through the platform or you can pick and choose modules at will. Originally I was going to walk through module by module but since I have the attention span of a gold fish and like to jump right into shiny things, I quickly finished my first module so that I could jump into Lightning Components. I’m not quite finished with it yet, but I’ve made it through 69% of the exercises and already have greatly improved my initial grasp of the concepts. (Three more to go and I get my badge!)

If you’re not quite sure what Lightning Components are, its basically the next step in Salesforce development. Its really more of a framework made up of re-usable and extendable UI components that you can use to work with your Salesforce data. These components can hold other components and they can be extended to create custom components that work on the Salesforce1 platform. At DF14 when they were announced you could only write Single Page Applications, but will soon have the ability to extend existing Salesforce1 screens. They’re javascript based on the front end and use an MVC type of approach to building the UI. That javascript then talks to Apex on the Salesforce side.

Back to trailhead: The Lightning Components module starts out with your basic Hello World application and gets you on the ground running right away. The challenges aren’t so difficult that one wants to just toss it out, but they also leave you with plenty of room to stretch your own ideas and play some “what if” scenarios. (Actually my last unit was on the event handling and when I was done I tried to run the example and had some unexpected results, but with a little poking I was able to figure out how to get it functioning. As it turns out, the next chapter was going to cover what I’d just done (…its like they read my mind!)

The module moves on to creating a “reservations” type application where you create a form where users can “register for an event.” So its an completely relatable topic as well. Often times some examples on other sites are so out there, and so “basic” that you really don’t learn much. Not the case here. I’m not sure how they did it, but whatever it is they did, they did it right.

You can tell these modules are put together with a well thought out execution plan. The lightning components module especially seems to have most definitely been put together by developers for developers, but yet they are simple enough that even non-developers can jump in and start exploring (though some knowledge of javascript is probably advantageous).

Trailhead itself keeps you coming back as well. The gamification concept with the badges makes you feel like you are getting somewhere. While I haven’t scored by Lightning Components badge yet (I do have a job ya know…), its the desire to have that little logo on my profile and the ability to tweet my achievement out to the world that keeps me driving forward, all the while tricking me into learning something. How dare they teach this old dog new tricks! :)

In a world that is quickly going mobile, Salesforce is poised to lead the way and learning Lightning Components will put you at the forefront of this tidal wave. So grab a surfboard and paddle over to Trailhead and prepare yourself for the future.

I’d love to help you along the way if I can, so if there is something you’d like me to try and/or talk about or do a “deep dive” on, let me know in the comments.

:wq!