0

I have a trigger on a custom object. The code works fine when I put it in a trigger file but it does not work when I try putting it in a handler class and then calling the method from the trigger.

Trigger Handler Class:

public class LoanTriggerHandler {
    
    public static void checkSubject() {
        
        Set<Id> bookIds = new Set<Id>();
        Set<Id> readerIds = new Set<Id>();

        // Find all unique referenced books and readers
        for (Loan__c loan : Trigger.new) {
            bookIds.add(loan.Book__c);
            readerIds.add(loan.Reader__c);
        }
    
        // Load the unique book and reader records so we have access to the subjects
        Map<Id, Book__c> booksById = new Map<Id, Book__c>(
            [SELECT Id, Subject__c FROM Book__c WHERE Id IN :bookIds]);
        Map<Id, Reader__c> readersById = new Map<Id, Reader__c>(
            [SELECT Id, Subject__c FROM Reader__c WHERE Id IN :readerIds]);
    
        // Check that the newly created loans have matching book and reader subjects
        for (Loan__c loan : Trigger.new) {
            if (booksById.get(loan.Book__c).Subject__c !=
                readersById.get(loan.Reader__c).Subject__c) {
                loan.addError('BOOK AND READER SUBJECTS MUST BE SAME');
            } 
        }
        }

}

Calling method from Trigger:

trigger LoanTrigger on Loan__c (before insert) {
    
    if(Trigger.isBefore) {
     LoanTriggerHandler.checkSubject(Trigger.New);
    }
    
}

When I try to save, it gives me the following error:

enter image description here

1
  • 1
    Please include error(s) as text, not images.
    – Adrian Larson
    Jul 11 at 1:00
1

You're passing in a parameter:

 LoanTriggerHandler.checkSubject(Trigger.New);

But you didn't define the parameter:

public static void checkSubject() {

Change it to:

public static void checkSubject(Loan__c[] loanRecords) {

And then change every instance of Trigger.new in your class to use loanRecords instead:

    for (Loan__c loan : loanRecords) {

This is the more-or-less standard way of writing trigger handler classes.

1

This is because your Apex class method needs to have a parameter that accepts a List of Loan__c records.

Your apex class should be as below

public class LoanTriggerHandler {

public static void checkSubject(List<Loan__c> newLoanRecords) {
    
    Set<Id> bookIds = new Set<Id>();
    Set<Id> readerIds = new Set<Id>();

    // Find all unique referenced books and readers
    for (Loan__c loan : newLoanRecords) {
        bookIds.add(loan.Book__c);
        readerIds.add(loan.Reader__c);
    }

    // Load the unique book and reader records so we have access to the subjects
    Map<Id, Book__c> booksById = new Map<Id, Book__c>(
        [SELECT Id, Subject__c FROM Book__c WHERE Id IN :bookIds]);
    Map<Id, Reader__c> readersById = new Map<Id, Reader__c>(
        [SELECT Id, Subject__c FROM Reader__c WHERE Id IN :readerIds]);

    // Check that the newly created loans have matching book and reader subjects
    for (Loan__c loan : newLoanRecords) {
        if (booksById.get(loan.Book__c).Subject__c !=
            readersById.get(loan.Reader__c).Subject__c) {
            loan.addError('BOOK AND READER SUBJECTS MUST BE SAME');
        } 
       }
    }
 }

Notice below edits,

  1. Accept List<Loan__c> as parameter

    public static void checkSubject(List<Loan__c> newLoanRecords) {

  2. Instead of trigger.new use the parameter

      // Find all unique referenced books and readers
     for (Loan__c loan : newLoanRecords) {
    
  3. Instead of trigger.new use the parameter

      // Check that the newly created loans have matching book and reader subjects
     for (Loan__c loan : newLoanRecords) {`
    

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.