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, 2021 at 1:00

2 Answers 2

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) {`
    

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .