Archive

Archive for the ‘Apex’ Category

Getter Method Order and Visualforce Pages

August 24th, 2010 11 comments

I recently had a Visualforce page that was working perfectly for over two years. This thing was solid, a workhorse, one of the most used pages I have ever created. Then one day it stopped working as expected. It wasn’t a big deal really, simply an warning message wasn’t being displayed to the users. All unit tests still passed and I had made no major changes to the code. What the crazy I thought?!? The only thing I may have done at some point in the past was make minor changes to the the layout or updated the page API version.

The way I architected the page from the very first day created a ticking time bomb that would show up two years after the page was created. Enter the world of Visualforce page generation and getter method order. Before I get to the juicy good stuff I’ll briefly explain how Visualforce pages are created…at a very high level.

1) Apex constructor code is run
2) Page generation begins
3) As the page starts to convert Visualforce markup to html it will see certain markup ( {!showWarning} ) on the Visualforce page related to variables in the controlling class
4) The page generation engine will be like, “Yo, controller, what up? Send me the variable showWarning” or “Hey, controla-homie, send me the list of accounts”. This is the GET of a specific variable.
5) The page generation engine can then embed the variable on the page as html output or perhaps use it to determine if pieces of the page should be rendered at all, such as a warning message
6) HTML is then fully created and sent to the browser making the request

Next lets take a little quiz. If you think quizzes are lame (I do) pretend this is a challenge of intellect that if solved will save the world from invading aliens. Ya, that’s a little weird and makes my sound crazier than I thought it would but let’s run with it. Take a look at the the code below. First the page:

<apex:page Controller="GetOrder">
 
	<apex:pageMessage title="Large Account Alert" severity="warning" strength="1" rendered="{!showLargeAcctWarning}"/>
 
	<apex:pageBlock >
		<apex:pageBlockTable value="{!accounts}" var="a">
			<apex:column value="{!a.Name}"/>
			<apex:column value="{!a.Name}"/>
			<apex:column value="{!a.NumberOfEmployees}"/>
		</apex:pageBlockTable>
	</apex:pageBlock>
</apex:page>

And then the class:

public class GetOrder{
 
    public Boolean showLargeAcctWarning {get; set;}
    List<Account> accts;
 
    public List<Account> getAccounts(){
        if(accts == null){
            accts = new List<Account>();
 
            for(Account a : [Select Id, Name, NumberOfEmployees from Account limit 5]){
                accts.add(a);
                if(a.NumberOfEmployees > 5){
                    showLargeAcctWarning = true;
                }
            }
        }
        system.debug(showLargeAcctWarning);
        return accts;
    }
}

Do you see anything wrong? If not, then you are a n00b and I laugh at your n00biness while I sit upon my white stallion. Just kidding, I’ve been working with Visualforce since the beginning and I only recently realized what is wrong with the code above. Not kidding about sitting upon a white stallion though. If you do see a problem you are officially a l337 \/I5U4lf0(3 haxor.

So what is the problem? The page should display a warning message if the Number of Employees is greater than 5, right? Wrong! Well… maybe. You can view the actual page above be clicking here. You will see the warning message is not displayed but the list definitely has accounts with more that 5 employees? What is going on here…..queue the Twilight Zone music (just to be clear, the Twilight ZONE, not the dumb sparkly vampire Twilight), you have just crossed over into the Visualforce Getter Zone, dun dun dunnnn.

Let’s take a look at the debug log to see what is happening. First let’s check the debug statement above to see if the show warning variable is being set to true.

screenhunter_07-aug-24-10-40

Hmm, the variable is definitely being set to true so why isn’t my warning being displayed. Let look a little deeper in to the log. Using the new Apex CSI log lets filter down to our get methods.

screenhunter_08-aug-24-10-42

If we look at this closely we will see the get method for the showLargeAcctWarning is called before the getAccounts methods. So when the page rendering and asks for the show warning variable it is false as it has not yet been set to true because the getAccounts method has not even executed yet.

So how to resolve this issue. Enter our knight in shining armor, the constructor. Rather than letting the page determine the order of get methods lets run them ourselves in the class constructor. When you execute code in the constructor it is guaranteed to run before the page generation process begins. Below is the updated code.

public class GetOrderFix {
 
    public Boolean showLargeAcctWarning{get; set;}
    List<Account> accts;
 
    public GetOrderFix(){ //This is the contructor, same name as class, will run before page generation begins
        getAccounts();
    }
 
    public List<Account> getAccounts(){
        if(accts == null){
            accts = new List<Account>();
 
            for(Account a : [Select Id, Name, NumberOfEmployees from Account limit 5]){
                accts.add(a);
                if(a.NumberOfEmployees > 5){
                    showLargeAcctWarning = true;
                }
            }
        }
        system.debug(showLargeAcctWarning);
        return accts;
    }
}

Now the getAccounts method is will run before page generation begins and when the generation engine asks for the show warning variable it will have a value of true. You can see the fixed paged here.

What can make these types of issues so hard to track down is that the order in which get methods are called have no official or documented process. What seems like minor change to your Visualforce markup could change the order in which get methods are called and this could cause your page to stop working properly. What I have started to do, and is probably a best practice I should have always been doing, is setup all initial variables, lists, etc in the constructor. Do this and it should minify your problems… at least with getter method order.

Categories: Apex, Visualforce

Choose My Next Blog Posts

July 13th, 2010 2 comments

I’ve got a pretty decent back log of super awesome and overwhelmingly exciting blog posts. Some related to force.com and some not. I’ve got so many that I can’t decide what is next so I need your help. Below are a few of the top choices. The only teaser is the title of the post.

On this poll you can select two options so make your votes count!

What should be my next blog post?

View Results

Loading ... Loading ...
Categories: Apex, Visualforce, salesforce

Serious Force.com Cookie Security Issue

June 25th, 2010 8 comments

UPDATE:
Before you read the update I would encourage you to read the original article below first.

This is not a bug but an expected issue with the way force.com sites pages are cached. For some reason in my crazy head I thought the only items cached on pages where the html structure, images, css, etc. I thought that even on cached pages the controller would execute on every load of the page. This is not true. The controller will only execute once when a page is not cached. Any subsequent visits while the page is cached will not cause the controller to execute. So if you are populating dynamic data on the page with Apex it will stay there for the next 10 minutes.

This becomes a major issue with pages that depend on cookies and customizing the site content per visit.

I’ve recommended that salesforce.com update their documentation with two big red bold updates:
1) Cached pages will not execute the controller on load
2) Pages that use cookies to display dynamic data should never be cached

I hope this is helpful to someone out there as I definitely learned something today.

Additional info can be found here: dev board post.

-Jason


Original Post:

I have discovered a major bug with the new cookie feature released in the Summer 10 edition of salesforce.com. Let’s get straight to the point. Cookie data is being passed across different browsers, different computers, and different users. Yes, you heard this right. Sounds unbelievable so I created a video that shows this happening. Clearly this is a major issue if you are storing session or personal information in cookies.

Before anyone rips into me for blogging about what could be a very significant security issue I have already notified salesforce.com and it is a high priority issue. I also believe it is best to get this information out to other force.com developers before they build something that depends on this functionality and this issue causes major problems for them.

At this point I highly recommend not using the new cooking feature until more information about this issue or a fix is released.

Page:

<apex:page controller="CookieBug" expires="60">
    <apex:form >
        <apex:inputText value="{!input}"/>
        <apex:commandButton value="Update Cookie" action="{!updateCookie}"/>
    </apex:form>
</apex:page>

Controller:

public class CookieBug{
 
    public String input {get; set;}
 
    public CookieBug(){
        //Autofill input based on cookie value
        Map<String,Cookie> cookies = ApexPages.currentPage().getCookies();
        if(cookies.size() > 0){
            if(cookies.get('myCookie') != null){
                input = cookies.get('myCookie').getValue();
            }
        }
    }
 
    public void updateCookie(){
        List<Cookie> cookies = new List<Cookie>();
        Cookies.add(new Cookie('myCookie',input,null,15552000,false));
        ApexPages.currentPage().setCookies(cookies);
    }
}

Seattle Force.com Developer Meeting – June 2010

May 28th, 2010 No comments

UPDATE: I’ll be demoing how to authenticate with OAuth using Force.com and how this can be used with the Twitter API.

It’s that time again for the Seattle Force.com Developer Meetup. Details below…

When: 6/3/2010 4:00 PM – 6:00 PM Pacific Daylight Time
Where: 7 Simple Machines Office
Subject: Seattle Force.com User Group Meeting – June 3
Comments: This month, our meeting will be held in a new venue. 7 Simple Machines has offered up a change in venue for us in June.

Location:
Their office is located at:
800 Maynard Ave S, Suite 208
Seattle, WA 98134

http://www.7simplemachines.com/views/ContactUs.aspx

As always, bring your any ideas and questions to the meeting to discuss with everyone!

Seattle Force.com Developer Meeting – May 2010

May 5th, 2010 No comments

I really need to get better about posting these earlier but if you are able to make it to the Seattle Force.com Developer Meeting we would love to have you stop by. All are welcome, pros and noobs. Below is the info regarding the upcoming meeting.

Our next Force.com user group meeting will be held on Thursday, May 6th.

Time: 4:00pm – 5:00pm PDT
Location: WMP Seattle
1215 4th Ave, Suite 1010
Seattle, WA 98161

Richard Saunders and Evan Callahan will be presenting their Client Management System.

As always, we are looking for people to present at our future meetings, so please let me know if you would like to share something with the group.

Categories: Apex, Visualforce

Seattle Force.com Developer Meeting

March 31st, 2010 No comments

There is a another force.com developer meeting for Seattle coming up this Thursday. If you are in the Seattle area and want to meetup or learn more about developing on the force.com platform please stop by.

Just a friendly reminder that this Thursday, April 1st at 4:00pm will be the our monthly meeting.

The meetings as always will be held in the West Monroe Partners office located at:

1215 4th Ave, Suite 1010
Seattle, WA 98161

This session will be an open forum so bring any questions, problems, and/or issues you have so we can discuss with the group.

If you have something cool you’d like to show off or present let me know and we can arrange for you to speak at one of the upcoming sessions.

Seattle Force.com Developer Group

March 3rd, 2010 No comments

Heads up that if you are a Force.com/Salesforce developer or want to learn more about force.com development in the Seattle area there is a meeting this Thursday, the 4th.

The meetings as always will be held in the West Monroe Partners office located at:

1215 4th Ave, Suite 1010

Seattle, WA 98161

When:  Thursday, March 4th, 2010

Start Time: 4:00 PM

This session will be an open forum so bring any questions, problems, and/or issues you have so we can discuss with the group. If we finish early, we can maybe grab a beer at one of the local bars downtown.

If you are interested even a little please stop by.

Categories: Apex, Technology, Visualforce

If Computers Could Barf – Salesforce Debug Log

March 1st, 2010 15 comments

This story starts some time ago. I have been complaining about the system/debug log in salesforce.com ever since they released what I would consider version 1.1. You can see my post here, Please fix the Debug Log!, pleading for salesforce to fix the debug log. This was back in July of 2008! From what I can tell there has only been two noticeable changes with this debug log. I will refer to them as version 1.1 which was implemented around the time of the message board post above and the the most recent Spring ’10 incarnation which I will refer to as version 2.0.

Read more…

Categories: Apex

How many lines of Apex code do you have?

February 9th, 2010 4 comments

I have always been curious how many lines of Apex code I have written. Is it a couple hundred (haha, ya right), several thousand, a gazillion million trillion? There was never really a good way to figure this out unless you pulled down all of the data and inspected it file by file. Lame.

Read more…

Categories: Apex

If Visualforce Blows, This Sucks

January 11th, 2010 55 comments

I recently saw a tweet that included nothing but a link and a lot of salesforce.com related tags.

Visual Force Blows (link was shortened in original tweet so I couldn’t see title)

What could this be I pondered? A new product announcement? A glowing review of the force.com platform? Upon clicking the link I entered the “I hate Apex and Visualforce Zone” (Dun Dun Dunnnnnnnnnnn). Some dude on a blog (man, everyone has a blog now days) is trying to build a dynamic link menu with data pulled from salesforce objects and using visualforce to display. This seems pretty normal right? Let us check out some excerpts first:

On Apex and Visualforce:

Sounds great in theory, however in reality it makes you want to stab yourself. A lot.

I on the other hand would bathe in it if I could. Oh ya….Visualforce and Apex, sooo bubbly clean. Ya, that was weird. Let’s move on.
Read more…

Categories: Apex, Visualforce

Seattle Force.com Developer Meeting

January 6th, 2010 No comments

Tomorrow, January 7th, there will be another Force.com Developer Meeting in Seattle (first Thursday of every month). If you develop on the Force.com platform with Apex, Visualforce, use the API, or want to learn more about these topics please feel free to join us.

Date: Thursday, January 7th.

Time: 8:00 – 10:00 AM PST

Location: West Monroe Partners
1215 4th Ave Suite 1010
Seattle, WA 98109

The West Monroe Partners office is located on the 10th floor.

Public Parking garages are located in the building, as well as in a 1-2 block radius. The area is also well serviced by public transportation.

The agenda for this meeting will be as follows:

  • Presentation/Demo – Jason Venable (tehnrd.com) will be demoing his runner up application he created for the most recent Force.com Cloud Developer Challenge. The site is GameForce and includes two games: Blackjack and multiplayer connect four. (http://tehnrd-developer-edition.na7.force.com/gamehome). It was built with 100% Force.com, no flash or JavaScript. Jason is a Salesforce.com Admin and Developer at F5 focused mainly on process automation for the worldwide sales team.
  • Open forum – opportunity to discuss any questions/issues you may have about all things Salesforce

If you are planning on attending this month’s meeting, please send me an email (vgrasparil@westmonroepartners.com) to RSVP.

If you would like to present an application you have built or share some best practices you have learned with the group, please let me know so we can schedule it into a future meeting.

See you on January 7th!

Yup, thats me! I’ll be showing off the gaming site I built on force.com, http://www.tehnrd.com/gameforce/. I’ll show off the basic UI stuff but we will also peel back the covers to see how it works the magic on the back end.

Categories: Apex, Visualforce

Batch Apex Status Bar

December 18th, 2009 8 comments

Batch Apex is here and it is cool. In some of the demos and webinars salesforce.com has put together you may have seen a status bar that represents how far along a batch job has proceeded. This is useful as you only need but a quick glance to see how your batch jobs are doing. Below is an image of what this would look like.

batchstatus

All of this magic status bar stuff is pretty simple. You have two divs, an inner and an outer that construct the status bar, the inner being the percent complete. All of the info to construct this status bar is located in a sObject called AsyncApexJob. This stores information about your batch jobs and other asynchronous operations.

The two important fields in this object are JobItemsProcessed and TotalJobItems. When a batch job is executing it may process millions of records but it will break these up into batches of 200, or less if defined……hence the name Batch Apex. So if I have 5,000 records to be processed there would be 25 batches of 200. In the AsyncApexJob object these 25 batches would be the TotalJobItems. As the job runs the number JobItemsProcessed will increase as the batches are completed.

Now that we have these two number calculating the percent complete is an utterly simple division equation. JobItemsProcessed divided by TotalJobItems times 100 gives us the percent complete. We then pass this value to the width of the inner div and our status bar is complete! To give the status bar the appearance of being animated we add an actionPoller to the page and rerender the table of batch jobs every five seconds which will intern update that status bar with the new values.

As always there is a fun little demo to play with and you can access that here: Click here for nifty cool demo.

I’ve also packaged up this component so you can install it directly to your org. You can download it here.

Here is all the code and markup. First the page that will contain the batchJobs component.

<apex:page controller="batchStatus">
    <apex:form>
        <apex:commandButton value="Start Batch Job" action="{!startBatch}" reRender="jobs,error"/> 
        <apex:outputText id="error" value="{!error}" style="font-weight: bold; color: red"/>
 
        <br/><br/>
        <c:batchJobs id="jobs" numberOfJobs="20"/>
    </apex:form>
</apex:page>

Next we have the Visualforce component:

<apex:component controller="batchJobs" selfClosing="true">
    <apex:attribute name="numberOfJobs" type="Integer" assignTo="{!numberOfJobs}" description="The number of batch jobs to display in the table."/>
 
    <!-- Here is the css styles that will be used for the progress bars -->
    <style>
        .progressBar{
            background-color: #f8f8f8;
            border:1px solid #DDDDDD;
            height: 19px;
            width: 300px;
            -moz-border-radius: 5px; 
            -webkit-border-radius: 5px;
        }
        .progress{
            background-color: #F7B64B;
            border:1px solid #E78F08;
            height: 100%;
            margin: -1px;
            text-align: center;
            -moz-border-radius: 5px; 
            -webkit-border-radius: 5px;
            line-height: 18px;
        }
    </style>
 
    <!-- This action poller will check the status of the batch jobs every 5 seconds -->
    <apex:actionPoller rerender="jobs" interval="5"/>
 
    <apex:pageBlock title="Batch Apex Jobs">
        <apex:pageBlockTable value="{!batchJobs}" var="b" id="jobs">
            <apex:column headerValue="Apex Class" value="{!b.job.ApexClass.Name}"/>
            <apex:column value="{!b.job.CreatedDate}"/>
            <apex:column value="{!b.job.CreatedById}"/>
            <apex:column value="{!b.job.Status}"/>
            <apex:column width="320px" >
 
                <!-- Here with have two divs that construct our progresses bar. An outter which is the entire bar,
                and and inner that represents the percent complete. We simply pass the percentComplete value to
                the inner div width and this will show how far along the job is. Brilliant! -->
 
                <div class="progressBar">
                    <div class="progress" style="width: {!b.percentComplete}%;">
                        {!b.percentComplete}%
                    </div>
                </div>
 
            </apex:column>
            <apex:column value="{!b.job.CompletedDate}"/>
        </apex:pageBlockTable>
    </apex:pageBlock>
 
</apex:component>

And finally the custom controller for the component….. where all the magic happens:

public class batchJobs{
 
    public List<BatchJob> batchJobs;
    public Integer numberOfJobs {get; set;}
 
    public List<BatchJob> getBatchJobs(){
        //Create new list of BatchJobs, a wrapper class that includes the job and percent complete.
        batchJobs = new List();
 
        //If number of jobs was not defined, default to 20
        if(numberOfJobs== null || numberofJobs <= 0){
            numberofJobs = 20;
        }
 
        //Query the Batch apex jobs
        for(AsyncApexJob a : [select TotalJobItems, Status, NumberOfErrors, MethodName, JobType, JobItemsProcessed, Id, CreatedDate, CreatedById, CompletedDate, ApexClassId, ApexClass.Name From AsyncApexJob order by CreatedDate desc limit :numberOfJobs]){
            Double itemsProcessed = a.JobItemsProcessed;
            Double totalItems = a.TotalJobItems;
 
            BatchJob j = new BatchJob();
            j.job = a;
 
            //Determine the pecent complete based on the number of batches complete
            if(totalItems == 0){
                //A little check here as we don't want to divide by 0.
                j.percentComplete = 0;
            }else{
                j.percentComplete = ((itemsProcessed  / totalItems) * 100.0).intValue();
            }
 
            batchJobs.add(j);
        }
        return batchJobs;
    }
 
    //This is the wrapper class the includes the job itself and a value for the percent complete
    public Class BatchJob{
        public AsyncApexJob job {get; set;}
        public Integer percentComplete {get; set;}
    }
 
    /*--------------------TEST METHOD------------------------*/
    static testMethod void batchStatusBarTest(){
        batchJobs controller = new batchJobs();
        controller.getBatchJobs();
    }
}

I initially planned on adding all sorts of cool features to this component such as color coding the status bar based on the status of the job and estimated time to completion. These were axed in 1.0 as it was taking too long and there our some other cool posts I have lined up that I want to get working on. Maybe in the future I’ll post an updated version of this component with all the flair it deserves.

UPDATE:

I’ve been asked a couple times what exactly happens when a user clicks the <apex:commandButton value=”Start Batch Job” action=”{!startBatch}” reRender=”jobs,error”/> button. This calls a very simple method in the controller that starts a batch job.

public void startBatch(){
	error = '';
	batchJob job = new batchJob();
	List<AsyncApexJob> openJobs = [select Id from AsyncApexJob where Status = 'Processing' OR Status = 'Queued']; 
 
	if(openJobs.size() < 5){
	        ID batchprocessid = Database.executeBatch(job);
	}else{
		error = 'WHOA BUDDY! Only five batch jobs at a time.';
	}
}

And here is the batch apex job.

global class batchJob implements Database.Batchable<SObject>{
 
    global database.querylocator start(Database.BatchableContext bc){
        return Database.getQueryLocator('select Id, Name from Account where Type = \'Batch Test\'');
    }
 
    global void execute(Database.BatchableContext bc, sObject[] objects){
        List<Account> accns = new List<Account>();
 
        for(sObject s : objects){
            Account a = (Account)s;
            a.Description = 'batch testing. blah blah blah.  ' + system.now();  
            accns.add(a);
        }
        update accns;
    }
 
    global void finish(Database.BatchableContext bc){
       system.debug('all done');
    }
}
Categories: Apex, Visualforce

Error Handling, Savepoints, and Inserts

October 19th, 2009 2 comments

I’ve been working with Apex for a little over two years now and I still learn little tips and tricks all the time.

Today I ran in to a somewhat peculiar problem when trying to catch errors on the insertion of a record. Here is the scenario in super pseudo apex code.

1) Set a database save point with Apex
2) Insert a record with Apex
3) Some type of validation error prevents the record from being inserted
4) Using a try-catch statement catch the error and display it to user
5) Roll back to your Database savepoint
6) Allow the user to fix the error.
7) When the save occurs the second time I would receive this error: “cannot specify Id in an insert call”

Huh, wait….what? The insert failed because of the validation rule, right? Kinda, sort of, it’s not really clear. Even though the insert failed my object in memory was still being assigned an Id. This caused a problem when trying to insert the second time.

I’m guessing salesforce.com sets the ID of a record before the insert as you can’t set values after inserts as the object would become read-only. Similar to how triggers work, you can only write values before inserts and updates, not after. When the operation fails the Id in the code is not removed. This is a giant guess on how the process works and it could be totally wrong.

So how to get around this problem? The solution is fairly simple. In the catch section of the code we want to clone the record without preserving the Id and assign this clone back to the original object. Something like this:

Savepoint sp = Database.setSavepoint(); 
try{		
	insert object;
}catch(exception e){
	Database.rollback(sp); 
	object = object.clone(false);
	return null;		
}

The false parameter in the clone method makes an exact copy of the object without preserving the Id. So the next time the user attempts to save, the Id is null, and there should be no issues.

Categories: Apex

Apex Flow Control – Preventing Infinite Loops

October 2nd, 2009 6 comments

When you build your first few triggers everything is so peaceful. The grass is green, the birds are chirping, and everything is working wonderfully. You continue to develop more triggers, classes, batch jobs, @future classes, and then one day your realize, “Great Scott!, I have created a monster”. If you connected all the classes and triggers that were related it would look like a giant spaghetti dinner.

When this happens you will undoubtedly run into one very specific problem. You have a piece of code A that causes code B to execute which then causes code A to execute which then causes code B to execute. OH NO! Infinite loop, governor limits AHHHHH!

Fear not! For there is a very simple solution to this problem. The extremely clear and concise diagram below shows a common scenario.

flowj

Let’s say we have an update trigger that sends a group of objects to be processed by an @future asynchronous method. There is a good chance this method will need to update the records. This would normally cause the trigger to execute and the @future method to be called again, hence our unstoppable loop. So how do we stop this loop? Before we perform the update on the records we need to say, “Hey, this is a update from a @future methods, don’t do anything”. We can do this by creating a simple Boolean value in a utility class and can be accessed by anycode in context of the update operation.

Below is the code of how something like this would work. First let’s look at the very simple solution. Yup, this is it. Some minor changes to our @future and trigger code and this is it.

public class utility{
 
    public static boolean isFutureUpdate;
 
}

Here is the trigger, we only want the code in this trigger to execute if the isFutureUpdate variable is not true.

trigger updateSomething on Account (after insert, after update) {
 
    /*We only want this trigger to perform it's logic when the
    update is not from an @future method */
    if(utility.isFutureUpdate == null || utility.isFutureUpdate == false){
 
        Set<Id> idsToProcess = new Se<Id>();
 
        for(Account acct : trigger.new){
            if(acct.NumberOfEmployees > 500){
                idsToProcess.add(acct.Id);
            }
        }
 
        //Send Ids to @future method for processing
        futureMethods.processLargeAccounts(idsToProcess);
 
    }
}

And here is our @future method. The only thing we need to add is one line of code to set the isFutureUpdate variable to true before we perform the update.

public class futureMethods{
 
    @future
    public static void processLargeAccounts(Set<Id> acctIDs){
 
        List<Account> acctsToUpdate = new List<Account>();
 
        /* Do awesome stuff with apex code */
 
        /*Before we perform this update we want to set the 
        isFutureUpdate boolean in our utility class to true */
        utility.isFutureUpdate = true;
 
        /*Now we can perform the update. The trigger will still 
        fire but none of the code inside of it will execute and
        this method will not be called again*/
        update acctsToUpdate;
    }
}

Now when the trigger is fired the @future method will not be called again.

This example shows the interaction between asynchronous operations but you can use this same solution if you have triggers that update triggers and cause a loop.

Categories: Apex

Seattle Force.com User Group

September 29th, 2009 1 comment

This is sort of a late notice but on October 1st there will be a Force.com user group in Seattle. If you are in the area and want to exchange ideas and best practices revolving around the Force.com platform please swing by.

Want to take a deeper dive into the technical capabilities of Salesforce? Would you like to meet other Force.com developers in the Seattle area? Interested in learning about new/different tools that will help you create and develop better solutions? A new Salesforce user group will be starting up on Thursday Oct 1. Meetings will be held on the first Thursday of every month.

We will try to cover a different range of topics at these monthly meetings such as:

  • Summary of new functionality in the upcoming release
  • Project spotlight where someone will demo their project and the technical details
  • Best Practices
  • 3rd Party development and integration tools
  • Apex and VisualForce
  • Open session to discuss specific questions you may have regarding your current projects

Time: 8-9am
Date: Oct 1, 2009
Location:

West Monroe Partners
1215 4th Ave Suite 1010
Seattle, WA 98161

Please contact Val Grasparil (vgrasparil@westmonroepartners.com) or Andrew Brown (abrown@westmonroepartners.com) if you have any questions.

Since it is in the morning, coffee and snacks will be provided. Please RSVP if you are planning on attending so we can make sure to have enough food for everyone.

Reach out directly to Val to RSVP. I’ve been told there is public parking available at the address above.