RSS feed for blog Linkin Skype Mail Me Twitter

Stickfight

SalesForce for Domino Dogs 3: Web Query Save Agents

“WebQuerySave” / “PostOpen” and all its siblings have been a bastion of Domino and Notes developments since time out of mind and indeed they exist in a near identical form in Salesforce but just called Triggers

Just like Notes/Domino has different events that let code ‘Do Stuff’ to records e.g. “WebQueryOpen”,”OnLoad”, “WebQuerySave” etc etc, Salesforce has the same sort of thing, in their case they are broken down into 2 parts: Timings and Events

Timings: Before and After

Before: The Event has been started but the record has not been saved, this maps basically to the “Query” events in Domino.

If you want to calculate fields and stuff and change values in the record you are saving, this is the time to do that, you don’t have to tell it to save or commit the records as you normally would, it will run a save after your code is run.

After: The record has been saved, all field values have been calculated, then the After event is run.

If you want to update other objects on the basis of this record being created/saved do it here, you can’t edit the record you are saving, but lots of useful bits such as the record id and who saved it are available in the After event 1

Events: Insert, Update, Delete and Undelete

These are exactly what they say there, Insert is like a new document creation, Update is editing an existing document, etc etc

This then gives us a total set of different event types of:

  • before insert
  • before update
  • before delete
  • after insert
  • after update
  • after delete
  • after undelete2

Now you can have a separate trigger for each of these events, but I have found that this bites you in the bum when they start to argue with each other and hard to keep straight when things get complex, so I just tend to have one trigger for all events and a bit of logic in it to determine what’s going to happen when

Here is my Basic template I start with on all my triggers

trigger XXXXTriggerAllEvents on XXXX (
    before insert,
    before update,
    before delete,
    after insert,
    after update,
    after delete,
    after undelete) {
            if(Trigger.isInsert || Trigger.isUpdate) {
                if (Trigger.isUpdate && Trigger.isAfter) {
                   MYScriptLibarary.DoStuffAfterAnUpdate(Trigger.New, Trigger.OldMap);
                } else if (Trigger.isInsert) {
                    //Do some stuff here to do with when a new document being create, like sending emals
                }
            }
}


As you can see you can determine what event you are dealing with by testing for “.isInsert” or “.isAfter” and then run the right bit of code for what you want, again I like to keep everything in easy sight, so use functions when ever I can with nice easy to understand names.

In the above case, I want to check a field after there has been an update to see if it has been changed from empty to containing a value. you can do this with the very very useful ‘Trigger.New’ and ‘Trigger.OldMap’) as you can see below

public with sharing class MYScriptLibarary {

    public static void DoStuffAfterAnUpdate(List<XXXX> newXXXX, Map<ID, XXXX> oldXXXX) {

                for (XXXX curentXXXX : newXXXX) {
                    if(!String.isBlank(curentXXXX.MyField) && String.isBlank(oldXXXX.get(curentXXXX.Id).MyField) ) {
                        system.debug('OMG!!! MYField changed DO SOMTHING');
                    }
                }

          }

}


So we are taking the list of objects3 that have caused the trigger to run ie “Trigger.New”, looping through them and comparing them to the values in the Trigger.OldMap (which contain the old values) to see if things have changed.


So that is the theory over, you can see existing triggers by entering Setup and searching for “apex triggers”



BUT you cant make them from there, you make them from the Object you want them to act on.

Lets take the Case object for an example



In setup you search for case, and click on “Case Triggers” and then on “New”



That will give you the default trigger…. lets swap that out for the all events trigger I showed above



Better, then just click save and your trigger will be live. simples..

Now there is an alternative way to make triggers, and you do sometime have to use it when you want to create a trigger for an object that does not live in the setup, such as the attachment object.



You will first need to open the Developer Console up (Select your Name in the top right and select “Developer Console”), then select File —> New —> Apex Trigger



Select “attachment” as the sObject and give it a sensible name.



And now you can do a trigger against an object that normally you don’t see.

Final Notes:
  1. Salesforce Process flows can fight with your triggers, if you get “A flow trigger failed to Execute” all of a sudden, go look to see if your power users have been playing with the process flows.
  2. Make sure you have security set correctly, particularly with community users, both security profiles and sharing settings can screw with your triggers if you cant write or see fields.
  3. As always make sure you code works if there are millions of records in Salesforce. CODE TO CATER TO LIMITS.

  1. You know that pain in the butt thing you sometimes have to do with Domino when you have to use the NoteID rather than that Document ID before a document is saved this gets round that issue. 

  2. Yes eagle eyes, there is no “before undelete”. 

  3. You are best to handle to handle all code in terms of batches rather than the single document you are used to in Domino, we will handle batching in a later blog, but just take my word for it at the moment 

Leave Your Comments

blog comments powered by Disqus

Related Entries

Modern Web Dev on Iseries

Coming Up For Air

Free beer and disreputable company

A Year in Review 2016

Ical Invites with Gmail tip

IBM Champion for 2017

The Perfect IBM Champion

SAML and Invalid Arguments

Sametime 9.0.1 and IP6

Salesforce Pardot: Multi Completion Rules

Razer Deathadder Chrome Sensitivity on Linux

MWLug 2016 Round-Up

To Find The Perfect Office

A Little Thing Done Right

Presenting at MWLUG

SalesForce for Domino Dogs 2: Scheduled Agents

SalesForce for Domino Dogs 1: Profile Documents

Editable salesforce templates

New Platform Type New Client Type

Engage 2016

LDCVia Webinar

Current Android Software 2015

Salesforce read mode hide-when hack

Classic Domino and multi country dates with Bootstrap

C3 charts on Saleforce Winter16

Updating Statamic on AWS

Icon UK 2015

Quiet Isnt it

Engage 2015

Conditional Checking in AngularJs using Restangular

IBM ConnectED2015 All work and no play

Learning A Lesson About Security from other People

2014 A Year In Review

IBM Connections Dev Update to V5

W.T.F. they made me an IBM Champion and a C-API tip

Bloody Android Kit-Kat and SD Cards

LDC Via Cross Post: Why oh why oh why (Part One)

Applet security: a blast from the past

UK ICON 2014

jQuery UK 2014 Day 2

jQuery UK 2014 Day 1

London Node.js User Group April 2014

Listen while you work

SQuirrel SQL For IBM Connections

Living Document: Connections Db Schema Versions

Connections Db Schema Tip2: Finding the UserID

Working from anywhere

Connections Db Tip1: getting the Connections db Schema version

CSC Event No.1

Engage 2014

IBM Connections Dev Links

Collaboration Stack Community Agenda and Stuff

Connections aide memoire 02: Backing Up Websphere Config

Inserting HTML into word documents

Connections aide memoire 01: Changing XML config

IBM Connect 2014 Slide Decks

IBM Connect 2014 Round up

Finding Me at IBM Connect 2014

Collaboration Stack Event

Commuting tip for Developers

My IBM Connect 2014 Sessions

IBM Connect 2014 session

Best USB Cable

The Perfect Consultant

First Tuesday Club November 2013

Latest Blogs