Wednesday, 30 December 2015

New Year, New Trailhead Badges

Badges

Overview

The Trailhead juggernaut keeps rolling, with a new trail and 6 (count ‘em) new badges, taking the totals up to 13 trails and 70 badges (not counting the community badges which you get for earning a new badge on a particular date, such as halloween, which is always tricky for those of us who already have all the badges, but these are the first world problems I am cursed with).

So What’s New?

  • Advanced Formulas
    This strikes me as an excellent fit for Trailhead, as the challenges will be tightly focused on a single formula field which satisfies a well-defined set of requirements. I’d imagine there was some competition in the team that writes the code that checks the challenges for this one.
     
  • Apex Integration Services
    If you haven’t done much of this before, get cracking. Its a good grounding in the topic and gets you writing code that carries out real integrations, but in a much safer environment than a customer org! 
     
  • Lighting Experience Chatter Basics
    One aimed more at the newbies than the experienced administrator or developer, which is a good thing as we want new people using the platform.

  • Lightning Data Management
    Getting data in and out. Useful information if you are considering a career with a Salesforce partner, as I guarantee that any project you work on will have some form of data migration, and it always takes longer than you expect!

  • Application Lifecycle Management
    Okay, so this is a rewrite rather than a new module. If you’ve taken this in the past you won’t be able to retake it, but if you held off waiting for some different words your masterful inactivity has paid dividends.

    and saving the best until last
     
  •  Build a Battle Station App
    A themed project to coincide with a film that you might have heard about. This kind of thing is what makes Trailhead fun and keeps it interesting. This is one of the few badges that I have remembered to add to my LinkedIn profile, which shows how valuable it is

So What’s Next?

I wish I knew. Or maybe I do and those pesky NDAs stop me from telling you. Unfortunately I don’t. But is that what the NDA forces me to say. Its all so uncertain.

One prediction I will make is that the number of badges will break 100 in 2016, and I’d expect this to happen around July/August time.

New Year, New You

As I mentioned above, there are now 70 badges available, so if you haven’t made a dent in them by the start of 2016 you’ll struggle to catch up and be forever chasing those last x badges.

Make a New Year’s resolution that will have real impact (on your career, your reputation, your battle station building capabilities) and resolve to earn more badges!

Related Posts

  

Saturday, 12 December 2015

Lightning Component Wrapper Classes

Lightning Component Wrapper Classes

Wrapper

Introduction

Wrapper classes are a common feature of applications built on the Salesforce platform. The class wraps an sObject and some additional data, hence the name wrapper. Typically wrapper classes are used to temporarily associate prpoerties with an sObject that are specific to the current scenario, and that do not make sense to add as fields to the sObject and persist to the database.

In this post I’ll show how you can use wrapper classes in a Lightning component, to wrap an account and a boolean property. This wrapper class allows a user to select one or more account names to view more details of the accounts.

 

Showmecode

The Apex Controller

My Apex controller makes a couple of methods available to the Lightning component. The first is invoked when the component initialises, and returns a collection of up to 10 accounts, with only the name and Id fields populated:

@AuraEnabled
public static List<Account> GetAccountNames()
{
	return [select id, Name from Account limit 10];
}

 the second method receives a JSON string representing a list of account ids (the accounts that the user has selected) and retrieves more details for those accounts:

@AuraEnabled
public static List<Account> GetAccountDetails(String idListJSONStr)
{
	Type idArrType=Type.forName('List<Id>');
	List<Id> ids=(List<Id>) JSON.deserialize(idListJSONStr, idArrType);
		
	return [select id, Name, Industry, Website from Account where id in :ids];
}

 Ideally I’d pass the Ids through as an array to this method, but attempting to pass arrays as parameter to Apex controller methods from a Lightning component results in an internal server error. At the time of writing (December 2015) this has been acknowledged as a bug for over a year, so its clearly one that is taking a bit of fixing! For a collection of primitives, the JSON string version works well, but when I need to send an array of complex objects (or sObjects) I usually place these inside a containing Apex class.

The Wrapper Class

I want my wrapper class to be available for use in both my component and in Apex, so that I can use the same one for Lightning and Visualforce. As I’ve written about before, custom apex classes are automatically converted to JavaScript objects for use client side, so to achieve this all I have to do is make the class properties available to the Lightning component via the AuraEnabled annotation:

public with sharing class AccountWrapper
{
	@AuraEnabled
	public Account acc {get; set;}
	
	@AuraEnabled
	public Boolean selected {get; set;}
}

(If I didn’t need to make use of this server-side, I’d just use JavaScript objects, which would make this post considerably shorter!)

The Lightning Component

The Lightning component has two sections - the first displays a list of account names and checkboxes for the user to choose accounts, and the second to display details of the chosen accounts:

<aura:component controller="AccountController">
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <aura:attribute name="wrappers" type="AccountWrapper" />
    <aura:attribute name="accounts" type="Account" />
    <span class="big">Choose Accounts</span>
    <table>
        <tr>
            <th class="head">Name</th>
            <th class="head">View?</th>
        </tr>
	<aura:iteration items="{!v.wrappers}" var="wrap">
            <tr>
                <td class="cell">
		    <ui:outputText value="{!wrap.acc.Name}" />
                </td>
                <td class="cell">
		    <ui:inputCheckbox value="{!wrap.selected}" />
                </td>
            </tr>
	</aura:iteration>
    </table>
    <button onclick="{!c.getAccounts}">Get Accounts</button>
    <br/>
    <br/>
    <br/>
    <span class="big">Selected Accounts</span>
    <table>
        <tr>
            <th class="head">Name</th>
            <th class="head">Industry</th>
            <th class="head">Website</th>
        </tr>
        <aura:iteration items="{!v.accounts}" var="acc">
            <tr>
                <td class="cell">
	    	    <ui:outputText value="{!acc.Name}" />
                </td>
                <td class="cell">
	    	    <ui:outputText value="{!acc.Industry}" />
                </td>
                <td class="cell">
	    	    <ui:outputText value="{!acc.Website}" />
                </td>
            </tr>
	</aura:iteration>
    </table>
</aura:component>

Note that the AccountWrapper custom class is defined as the type of the wrappers attribute that is used to display the accounts and their checkboxes. This allows me to supply the wrapper classes from the server in the future if for some reason I decide to go that route.

The Lightning Component JavaScript

The controller for the Lightning component contains a couple of methods that delegate to the helper and isn’t that exciting. For those that need the complete picture, its available at this gist.

The helper is much more interesting, but a bit large to drop into this post. It can be found at this gist, but the key aspects are covered below.

The wrapper class instances are created client side, which is really easy in JavaScript, mainly due to its loose typing. I can just define an object instance that contains an account and a selected property. In the snippet below, accs is the collection of accounts returned from the controller at initialisation:

var wrappers=new Array();
for (var idx=0; idx<accs.length; idx++) {
    var wrapper = { 'acc' : accs[idx],
			       'selected' : false
                            };
     wrappers.push(wrapper);
}
cmp.set('v.wrappers', wrappers);

Once the user selects the accounts and presses the getAccounts button, I can iterate the list of wrapper classes and pull the ids of the selected items, which I then turn into the JSON string: 

var wrappers=cmp.get('v.wrappers');
var ids=new Array();
for (var idx=0; idx<wrappers.length; idx++) {
    if (wrappers[idx].selected) {
        ids.push(wrappers[idx].acc.Id);
    }
}
var idListJSON=JSON.stringify(ids);

The Lightning Component Styling

In order to make the page a bit more readable, there’s some styling around the component. This is also not particularly interesting but can be found at this gist.

The Application

In order to use this component, I’ve created a simple Lightning application:

<aura:application >
    <c:AccountWrappers />
</aura:application>

Opening the application displays the first 10 accounts retrieved from the database, which I can check the associated box to select:

Screen Shot 2015 12 12 at 16 55 05

and clicking the Get Accounts button retrieves details of those accounts and displays them:

Screen Shot 2015 12 12 at 16 56 07

Related Posts