0

I'm working on trigger that will [after insert] get Street from ContactPointAddress object connected via lookup (Contact__c) and re-write MailingStreet field in Contact object ONLY if checkbox isDefault is checked. This is what I've done so far:

public static void AfterInsert(ContactPointAddress[] lstContactPointAddresses)
        {
            List<Contact> allPassagersToBeUpdated= new List<Contact>();
            for (ContactPointAddress tmpContactPointAddress : lstContactPointAddresses)
                {
                    // created contactPointAddress is checked - is default
                    if (tmpContactPointAddress.IsDefault == true) {
                        Contact passenger = [SELECT Name,LastName,MailingStreet FROM Contact WHERE Id =: tmpContactPointAddress.Contact__c];

                        Address addressCompoundField = (Address)tmpContactPointAddress.Address;
                        passenger.MailingStreet = addressCompoundField.Street;
                        allPassagersToBeUpdated.add(passenger);

                    }
                    else {
                        return;
                    }

                }
            if(allPassagersToBeUpdated.size()>0){
                update allPassagersToBeUpdated;
            }

        } 

The problem is, my compound field Addres in Contact Point Address is always null. I don't know why as I can acces values of other fields. Can anyone help me please? Thanks a lot:)

p.s: my exact error is:

Trg_ContactPointAddress: execution of AfterInsert caused by: System.NullPointerException: Attempt to de-reference a null object Class.Trg_ContactPointAddress_Handler.AfterInsert: line 31, column 1 Trigger.Trg_ContactPointAddress: line 14, column 1


I tried to re-arrange the code in order to save SOQL calls to database and end up with sth like this:

    public static void AfterInsert(ContactPointAddress[] lstContactPointAddresses) {

        List<Contact> allPassengersToBeUpdated = new List<Contact>();
        set<Id> setOfPassengersIds = new set<Id>();

        for (ContactPointAddress tmpContactPointAddress : lstContactPointAddresses) {
            // created contactPointAddress is checked - is default
            if (tmpContactPointAddress.IsDefault == true) {
                setOfPassengersIds.add(tmpContactPointAddress.Contact__c);
            } else {
                return;
            }
        }

        map<Id, Contact> mapPassengers = new map<Id, Contact>([SELECT Id, MailingStreet FROM Contact WHERE Id IN :setOfPassengersIds ]);
        map<Id, ContactPointAddress> mapCPA = new map<Id, ContactPointAddress>([SELECT Id, Address FROM ContactPointAddress WHERE Id IN :lstContactPointAddresses ]);

        for(Contact passenger: mapPassengers.values()) {
            passenger.MailingStreet = ((Address)mapCPA.get(passenger.Id).Address).Street;
            allPassengersToBeUpdated.add(passenger);
        }


        if (allPassengersToBeUpdated.size() > 0) {
            update allPassengersToBeUpdated;
        }
    }

But still getting the same error

2 Answers 2

0

In order to use the Address class you'll need to query for the compound address field. In your case that will be MailingAddress. MailingStreet is only a part of the whole.

You will also need to use the getStreet() method on the Address object.

public static void AfterInsert(ContactPointAddress[] lstContactPointAddresses) {
    List<Contact> allPassagersToBeUpdated = new List<Contact>();
    for (ContactPointAddress tmpContactPointAddress : lstContactPointAddresses) {
        // created contactPointAddress is checked - is default
        if (tmpContactPointAddress.IsDefault) {
            Contact passenger = [
                SELECT Name
                        ,LastName
                        ,MailingAddress 
                FROM Contact 
                WHERE Id = :tmpContactPointAddress.Contact__c
            ];
            Address addressCompoundField = (Address)tmpContactPointAddress.MailingAddress;
            passenger.MailingStreet = addressCompoundField.getStreet();
            allPassagersToBeUpdated.add(passenger);
        } else {
            return;
        }
    }

    if(allPassagersToBeUpdated.size() > 0) {
        update allPassagersToBeUpdated;
    }

Additionally, it's a bad practice to make SOQL queries inside of a for-loop, especially when it looks like the code is called from a trigger. You will want to bulkify your code so that you query for all of your addresses at once. There are a number of good resources for this here and elsewhere.

2
  • Thank you for your answer. 1.) Unfortunately there is not such method "getStreet" and also there is not field Mailing address in Contact point Address. 2.) I'll try to fix select in for loop after knowing how to modify address but good point thanks
    – Majo
    Sep 25, 2020 at 20:43
  • What is the API version of your Apex class and are you trying to use Schema.Address or System.Address? The class System.Address has a getStreet method and Schema.Address has accessible properties: City, Country, Street etc. For better or worse, these two are closely named so it's ambiguous which one you want with Address but the documentation seems to indicate System.Address is used as the default but that may be API version dependent.
    – nbrown
    Sep 28, 2020 at 12:36
0

I see that you're trying to set the Contact's MailingStreet to the Street in the ContactPointAddress object that is related to the Contact. You can try the following codes:

public static void AfterInsert(ContactPointAddress[] lstContactPointAddresses) {

    List<Contact> allPassengersToBeUpdated = new List<Contact>();
    map<Id, String> mapCPA = new map<Id, String>();

    for (ContactPointAddress tmpContactPointAddress : lstContactPointAddresses) {
        // created contactPointAddress is checked - is default
        if (tmpContactPointAddress.IsDefault == true) {
            setOfPassengersIds.put(tmpContactPointAddress.Contact__c, tmpContactPointAddress.Street);
        } else {
            return;
        }
    }

    if (!mapCPA.isEmpty()) {
        map<Id, Contact> mapPassengers = new map<Id, Contact>([SELECT Id, MailingStreet FROM Contact WHERE Id IN :mapCPA.keyset()]);
    
        for(Contact passenger: mapPassengers.values()) {
            passenger.MailingStreet = mapCPA.get(passenger.Id);
            allPassengersToBeUpdated.add(passenger);
        }

        if (allPassengersToBeUpdated.size() > 0) {
            update allPassengersToBeUpdated;
        }
    }
}
2
  • Hi, I tried to implement your code but even if i changed type of "setOfPassengerId" to map a got error "Cannot resolve symbol 'Street'" from line 9 in your code. That is basically the whole problem that I cannot access variable Street from compound field Address right away from contactPointAddress
    – Majo
    Sep 26, 2020 at 5:50
  • Can you check if your apex class/trigger is on API version 49 or later?
    – Jason Fung
    Sep 26, 2020 at 13:11

You must log in to answer this question.

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