function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
justicepsych2justicepsych2 

Cross-Object Trigger

I'm having trouble with the following code.  I keep getting the error that there is no viable alternative on the "for(integer i...) line.  

 

 

trigger recipTechSurvey on Tech_Survey__c(after update, after insert){
List<Show__c> linkedShows = [SELECT id, Tech_Survey__c FROM Show__c WHERE Show__c.id IN :Trigger.newMap.keySet()];

 

for (Integer i = 0; i < Trigger.new.size(); i++) {
List<Show__c> showsToUpdate = new List<Show__c>{};
for(List <Show__c> ls: linkedShows, ){
             if (Trigger.new[i].ShowNum__c == ls.id) {
             ls.Tech_Survey__c= :Trigger.new[i].id; 
             showsToUpdate.put(ls.id, ls.Tech_Survey__c);
}
              } 

Database.update(showsToUpdate);
}


 
static testMethod void testrecipTechSurvey(){ Show__c show = new Show__c(name='testShow', Show_Num__c='14-2000'); insert show; Show__c setShow = [SELECT Id, Show_Num__c FROM Show__c WHERE Show_Num__c='14-2000']; Tech_Survey__c survey = new Tech_Survey__c(ShowNum__c=setShow.id); insert survey; Show__c s = setShow; System.assertEquals (s.Tech_Survey__c, setShow.id); } }

 

 
Best Answer chosen by Admin (Salesforce Developers) 
Jerun JoseJerun Jose

There are still some problems with your code.

 

trigger recipTechSurvey on Tech_Survey__c(after update, after insert){
	set<ID> showIDs = new set<ID>();
	for(Show__c sh : trigger.new)
		showIDs.add(sh.ShowNum__c);
	// Trigger.newmap will hold a map of the Tech_Survey__c record Id to the Tech_Survey__c record. So when you do Trigger.newMap.keySet() you will get a set of the Tech_Survey__c Ids, which you are trying to match against the Show__c field.
	List<Show__c> linkedShows = [SELECT id, Tech_Survey__c FROM Show__c WHERE Show__c IN :Trigger.newMap.keySet()];
	List<Show__c> linkedShows = [SELECT id, Tech_Survey__c FROM Show__c WHERE Show__c IN :showIDs];
	for (Integer i = 0; i < Trigger.new.size(); i++) {
		List<Show__c> showsToUpdate = new List<Show__c>();
		for(Show__c ls: linkedShows){
			if (Trigger.new[i].ShowNum__c == ls.id) {
				ls.Tech_Survey__c = :Trigger.new[i].id;
				ls.Tech_Survey__c = Trigger.new[i].id;
				// showsToUpdate is a list of Show__c records and so you cannot use the .put method. put is used for map collections.
				showsToUpdate.put(ls.id, ls.Tech_Survey__c);
				showsToUpdate.add(ls);
			}
		}
		Database.update(showsToUpdate);
	}
}

 Please note that your code is still not bug free but it will work for single record manipulations. Also, there are some improvements that can be made to get it more aligned to the best practises.

All Answers

Jerun JoseJerun Jose

Apex error messages can point you in the wrong direction at times. From experience I always look at the line before and the line after if I cannot see a problem with the line mentioned in the error message.

 

The line

List<Show__c> showsToUpdate = new List<Show__c>{};

needs to be changed to

List<Show__c> showsToUpdate = new List<Show__c>();

 

Also, the line

for(List <Show__c> ls: linkedShows, ){

needs to be changed to

        for(Show__c ls: linkedShows){

justicepsych2justicepsych2
Thanks so much! I'll try that!
justicepsych2justicepsych2

Nope. Still not working.  I'm trying to do something that seems like it should be incredibly simple. I have two custom objects that are linked by lookup, but cannot have a master-child relationship. 

 

What I am trying to do is simply trigger a reciprocal update, so that if one object is selected on a lookup, the other object has the corresponding lookup field populated with the other's id.

 

Am I overengineering?  Here's what I've got now, restructured.

 

 1   trigger recipTechSurvey on Tech_Survey__c (after insert, after update) {  2   List<Show__c> linkedShows = [SELECT id, Tech_Survey__c FROM Show__c WHERE Show__c.id IN :Trigger.newMap.keySet()];  3   Map<id,Show__c> showsToUpdate = new Map<id,Show__c>{};  4    for (Integer i = 0; i < Trigger.new.size(); i++){  5    for (Integer f = 0; f < linkedShows.size(); f++){  6    if(Trigger.new[i].ShowNum__c == linkedShows[f].id) {  7    Show__c s = new Show__c(Tech_Survey__c=Trigger.new[i].id);  8    showsToUpdate.put(s.id, s);  9    }  10    }  11    }  12   update showsToUpdate.values();  13

  }

 

 

}

 

 

AND here's the test method:

 

static testMethod void testrecipTechSurvey(){
    Show__c show = new Show__c(name='testShow', Show_Num__c='14-2000');
    insert show;
    
    Show__c setShow = [SELECT Id, Show_Num__c, Tech_Survey__c FROM Show__c WHERE Show_Num__c='14-2000'];

    Tech_Survey__c survey = new Tech_Survey__c(ShowNum__c=setShow.id);
    insert survey;
    
    Tech_Survey__c ts = [SELECT id, ShowNum__c FROM Tech_Survey__c WHERE ShowNum__c= :setShow.id];
    Show__c s = [SELECT Id, Show_Num__c, Tech_Survey__c FROM Show__c WHERE Show_Num__c='14-2000'];
    
    System.assertEquals (s.Tech_Survey__c, ts.id); 
}

Jerun JoseJerun Jose

There are still some problems with your code.

 

trigger recipTechSurvey on Tech_Survey__c(after update, after insert){
	set<ID> showIDs = new set<ID>();
	for(Show__c sh : trigger.new)
		showIDs.add(sh.ShowNum__c);
	// Trigger.newmap will hold a map of the Tech_Survey__c record Id to the Tech_Survey__c record. So when you do Trigger.newMap.keySet() you will get a set of the Tech_Survey__c Ids, which you are trying to match against the Show__c field.
	List<Show__c> linkedShows = [SELECT id, Tech_Survey__c FROM Show__c WHERE Show__c IN :Trigger.newMap.keySet()];
	List<Show__c> linkedShows = [SELECT id, Tech_Survey__c FROM Show__c WHERE Show__c IN :showIDs];
	for (Integer i = 0; i < Trigger.new.size(); i++) {
		List<Show__c> showsToUpdate = new List<Show__c>();
		for(Show__c ls: linkedShows){
			if (Trigger.new[i].ShowNum__c == ls.id) {
				ls.Tech_Survey__c = :Trigger.new[i].id;
				ls.Tech_Survey__c = Trigger.new[i].id;
				// showsToUpdate is a list of Show__c records and so you cannot use the .put method. put is used for map collections.
				showsToUpdate.put(ls.id, ls.Tech_Survey__c);
				showsToUpdate.add(ls);
			}
		}
		Database.update(showsToUpdate);
	}
}

 Please note that your code is still not bug free but it will work for single record manipulations. Also, there are some improvements that can be made to get it more aligned to the best practises.

This was selected as the best answer
justicepsych2justicepsych2

Thanks so much man.  Made some minor tweaks and overhauled the test methods and it works like a charm.  Much appreciation!