Wednesday, 29 March 2023

Lightning Web Component References in Spring '23

Introduction

Another week, another post about new LWC directives in 'Spring 23 - this time the lwc:ref directive. As the name suggests, this provides a reference to the component, one that can be used in JavaScript to access the element with a minimum of fuss.

Usage

To define a reference to a component, simply specify the lwc:ref directive in the HTML:

<h1 class="slds-var-m-bottom_small" lwc:ref="Heading1">Directives</h1>

and to access the element in JavaScript via the reference:

const headingEle=this.refs.Heading1;

As this.refs is an object, you can also retrieve a reference based on a variable:

const refVal='Heading1';

   ...
   
const chosenEle=this.refs[refval];

Notes/Gotchas

The reference value in the HTML markup must be a string literal - you can't use properties to dynamically generate the reference. This has the knock-on effect that you can't use it in loops to generate a unique reference for each element. If you try, you'll get an error similar to the following when you deploy or push your source:
     LWC1158:
         Invalid lwc:ref usage on element "<li>". lwc:ref cannot be used inside
         for:each or an iterator.

Hopefully this will change in a future release, as it's a key use case that has been a struggle since Visualforce days. 

You can, however, define multiple references with the same name - in this case the last one defined will win. I'm surprised that this isn't blocked by the platform, as it feels like a really easy mistake to make and one that I'm sure I'll encounter a lot over the next couple of years!

If you extract a reference that doesn't exist, in true JavaScript fashion it will return null rather than indicating an error. Always check your reference resolved to an element before taking any further action!

Why Use Refs

So why should we use references, when we can already provide a reference via a data attribute, and dynamically generate the value to boot? There are a few good reasons:
  •  Clarity. A data attribute is a generic mechanism for storing additional information on an HTML element - information that is useful to the application. In order to determine the purpose of this information, I need to examine the JavaScript to figure out how it is used. A reference, on the other hand, has a single purpose - to provide a way to locate the element based on the reference value - no need to look at any JavaScript. As mentioned above, I have to compromise on this clarity and fall back on data attributes to dynamically generate a value, but hopefully that will be coming soon.

  • Cleanliness. Data attributes appear in the rendered HTML, while references don't. This also has the benefit that you aren't exposing something you rely on to possible external interference or for someone else's code to rely on, thus creating an unexpected dependency.

  • Performance - my opinion! I'd also imagine that it's more performant to use references than executing selector queries - the this.refs object is built once, applies to the current template only, and I then extract elements anywhere in my JavaScript with no additional effort. Using selectors I have to execute a query each time I need an element, and I might need multiple selectors to find disparate elements by their attributes. This is the case in Vue.js which has it's own references implementation, so I'd imagine LWC is similar. 

Related Posts




Friday, 17 March 2023

Einstein GPT - Rise of the Machines?

The very first computer magazine that I bought, way back in February 1981, was an issue of Personal Computer World with a story entitled "THE LAST ONE". This was a revolutionary system where you described what you wanted the program to do in plain English and it generated the code for you. This was being sensationalised as the end of programmers as we know them, yet I've managed a fruitful career in the 4 decades since.

Plain English was doing a lot of heavy lifting here, and the reality was that you chose options from menus to build a flowchart that eventually generated BASIC code, but it was pretty cool for it's time. Fast forward 42 years and with Salesforce announcing Einstein GPT at TrailblazerDX 23, it appears we'll be able to describe our requirements in a plain text comment and the class will be generated for us. So does this finally mean the end of programmers as we know them? Once again I think that would be a premature conclusion to jump to. 

If you'll permit me another stroll down memory lane, I'll use a documentary on factory automation to explain why. This was a ceramics factory that produced, among other things, mugs. It was the job of the final worker on the assembly line to take the mug and place it in a cardboard box for shipping. The company had invested in automation and he'd been put on notice that he was to be made redundant as part of this push to automate all the things. The slight downside was that the robot that picked the mug off the assembly line and put it in the box wasn't initially very accurate. it was knocking mugs off the conveyor when it tried to pick them up, and often dropped them when swinging round to the cardboard box, resulting in huge breakage numbers. This worker was then retained to stand near the robot and catch the items that it knocked over or dropped! The robot was continually being adjusted and adapted to do a better job, so he was essentially acting as it's minder until it got smart enough not to need him, at which point he'd be let go.

I think that we are in the same situation with Einstein GPT (and all the other GPTs) - we can ask them to create something, they will have a go, but you still need a human there to check that they got it right and fix what they got wrong. For simple classes with a method or two, it will make a good fist of it, and the same for the test classes, but as the complexity rises it's likely to need more human intervention. Human guardrails if you will, ensuring things stay heading in the right direction.

What Einstein GPT will give us is very useful starting points, rather like templates. Just like templates of old this will remove the need for us to continually rewrite the same few lines of boilerplate code to declare a class, except that these templates will be ever evolving based on what is already present in our codebase, and generated on demand based on what we can articulate (for regular classes) or what a class currently looks like (for test classes). For simple requirements they may be a very good first cut that just needs a bit of polishing.

A real time and money saver if most of the code written is relatively straightforward, and a potentially huge productivity boost for junior developers, as long as it gets it right most of the time. Experienced developers should also get a productivity improvement - they'll focus more of their time on the hard stuff rather than setting up the basics.  

So will Einstein GPT take the jobs of Salesforce developers? I think not. 

Salesforce Developers that use Einstein GPT may take the jobs of Salesforce Developers who don't, especially if the majority of the development work is low complexity.




Saturday, 11 March 2023

Apex Roadmap: User Mode with Permission Sets

As has been the case since the first TrailheaDX in 2016, the stars didn't align so that I could attend in person. Luckily a lot of the content is already up on Salesforce+, including a very interesting session on the Apex roadmap from Daniel Ballinger and Chris Peterson. One feature that is currently in development really stood out for me - User Mode with Permission Sets. 

User Mode

User Mode went GA in the Spring 23 release of Salesforce, and is a real benefit for those of us with app exchange packages containing Apex code. For those who haven't attempted this and the associated security review, here's a brief summary of what you are up against with the previous tooling:

  • You need to respect the CRUD and FLS permissions set by the subscriber org (the Salesforce instance into which the package has been installed) administrator. This is of course quite right, otherwise your package could just help itself to confidential information that it has no business accessing.
  • There isn't much support in the platform for this, so you need to either create your own methods to check this for each object and field, or use one of the myriad third party offerings.
I've always been in agreement with this governance being enforced in the security review, and also of the strong opinion that if this is a requirement it should be baked into the platform, rather than pushed back on everyone that is developing a package with code. There must be tens of thousands of lines of code in all the packages out there, all re-solving the same problem. 

There were previous attempts to solve this, but they all had compromises. User Mode genuinely takes the transaction out of system mode so that all configured permissions apply for the database operation. If the database operation attempts to use fields or objects that aren't accessible, errors are returned for every disallowed item.

All well and good when you are respecting the admin's decision about access, but what happens if access to objects and fields managed by the package is required in order for the package to function correctly? You could put the user through death by a thousand cuts, allowing them to get slightly further each time before an error is thrown and they request additional permissions from their admin, or you can execute your database operations in System Mode.  This is quite the nuclear option though, as it opens up access to every object and field in the instance. If all you need is to get at the value for a single checkbox, it's an extremely large hammer to crack a small nut.

User Mode with Permission Sets


User Mode with Permission Sets allows you to select an appropriate sized hammer for the nut in question. Rather than elevating the user's access to everything, everywhere, you can give them the minimal amount of additional privilege required for your package to function correctly, just for the database operations that it is needed. To continue the example of needing access to a single checkbox value, you'd also package a permission set that grants access to just that field and execute the database operation in user mode plus that permission set. Much better from a security and governance perspective. 

Here's a code snippet snatched from the session - note that as this is still in development the syntax is likely to change, but it gives a sense of the direction of travel:



Packages aren't the only use case for this though, limiting the data that your Apex code has access to is good practice regardless of whether it's going into a package or being deployed directly to an org. Sadly it wouldn't stop my Evil Co-Worker, as when they have access to the code they can simply change it to run in System Mode in all cases. It will limit the impact of simple mistakes though, and keep your Information Security department a little happier.

More Information





Saturday, 4 March 2023

Such a Thing as a Free App Again

This post had a last minute change of tack, as Salesforce rowed back their plans to charge for security reviewing free apps. It's still something I wanted to publish, as I think free apps add real value to many customers and I'd hate to see them go away.

Earlier this year Salesforce announced changes to the way that app exchange listings are charged - a lot of us missed this, but Todd Halfpenny, one of my co-leaders of the London Salesforce Developers group, pointed us at it during the Feb event. Instead of a flat fee to list ($2550) and a yearly renewal ($150), the charges are switching to the security review - $999 per attempt. Apparently the stats showed that most apps take two attempts to pass the review, so for most publishers the cost would reduce slightly. So far so good. Then it turned out that these fees would also apply to free apps, whose costs to lists would go from $0 up front and $0 a year, to a minimum of $999 (potentially multiples of this) to list and an unpredictable cost for periodic re-reviews. Not such a good deal in this case. Obviously I understand that the security reviewers need to get paid, but for free apps it felt like something that Salesforce should invest in rather than pushing onto the publisher. 

I've listed a free app (BrightSIGN) since 2015, provided numerous bug fixes and enhancements, written blogs about how it use it in various scenarios, and supported end users when they had problems integrating it into their setup. All of this has been done in my own time at evenings and weekends. and I've never made a penny from it, or indeed tried to. In the interests of full transparency there may have been some marketing or other intangible benefits to my company - a few Salesforce people used it for demos which might have predisposed them to us over another partner, but I viewed this as a community contribution - something that a few hundred people a year found useful so worth a few hours of my time every month. To find out that in order to continue giving this away to Salesforce customers I was expected to cover any costs that the $170 billion company incurred didn't seem reasonable. 

When I read this I wasn't mad, just disappointed. Disappointed that none of the decision makers at Salesforce could see this was a bad look. Fleecing the very people who are already going the extra mile to help you is the kind of thing we expect from Mega Evil Corps, not Salesforce. 


I can understand charging for security reviews of freemium apps, as those are typically a sales channel for the full featured version, but free as in beer apps already represent a donation of someone's time. I can also understand that if there are bad actors chucking poorly written apps over the fence and relying on the security review to find all the issues, that they should feel some consequences. It should be targeting the problem with laser accuracy though, not taking out the rest of us who play by the rules as well.

When I submit my app for review I do everything possible to ensure it will pass - the submission requires a fair bit of effort on my part and I'd far rather only do it once. I go through the code with a fine-tooth comb to make sure it adheres to all the security requirements and I run it though the automated tools that Salesforce make available to me. Sadly, I still find that I fail at least once, with something that is either a new requirement or that the tooling I have access to doesn't pick up. If Salesforce are serious about ensuring that apps are in the best possible shape to pass the review, they should give us access to the same tools that they use. In a perfect world this would all be entirely automated and we'd just provide a link to the report showing we'd passed to the security review team. 

Another issue with this approach is the periodic re-review - often you have to go through this even if you've made no changes to your app since it passed the previous review. Salesforce being in full control of changing the requirements under you, mandating that you have to re-review, and charging you for it, feels like a process open to abuse. I'm not suggesting for a moment that they would use this as a mechanism to generate revenue, but if they did there's pretty much nothing we could do (aside from take to the socials!).

If Salesforce had pushed ahead with this plan, I would have pulled BrightSIGN from the app exchange without question. I might be able to get my company to cover app exchange fees, but that would involve a considerable amount of effort on my part to make the business case and there's no guarantee of success. I'd still publish it, but it wouldn't have the security review stamp of approval so potential users would have to decide if they trusted me or not. I'd likely supply the output from various security scanners, but there would be no way for anyone to prove that they applied to the package version that I was offering. I'd also tell everyone using it why I was having to do this, and I'm sure I'd bad mouth Salesforce quite a bit along the way.

While I'm a very trustworthy individual, I'm sure that some (like my evil co-worker) would be rubbing their hands at the thought of introducing disruptive packages into customer orgs. Like many attempts to block things in the past, it would just end up pushing them underground, almost certainly result in a less secure ecosystem, and give rise to the potential for data breaches that damage Salesforce's reputation. 

The good news it that Salesforce have decided, for now, not to charge for free app reviews after all. Hopefully this is a permanent change for apps that cannot be monetised, as long as we keep up our side of the bargain and bring our best work before the security review team. I can't help seeing the dabs of the activist investors all over this - not that I think they are determined to take down free apps, more pushing for every department to be profitable. Sometimes the costs need to be seen in a wider context - it might be a free app that turns a prospect into a customer, makes the difference at renewal time, or helps a non-profit with limited budget achieve their goals. I think that's worth investing in, which is why I built my app, and Salesforce should too.