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
Mark Z DeanMark Z Dean 

Map Returning Blank Values

I am trying to do an exercise from a Pluralsight course. Requirement is to get the lowest competitor price and populate the name of the competitor and the price:
User-added image

My code:
trigger CompetitorPrice5 on Opportunity (before insert, before update) {

    Map<id, Opportunity> BestPriceM = new Map<id, Opportunity>();

    //select all records into a map
    Map<id, Opportunity> m = new Map<id, Opportunity>([select id, competitor1__c, competitor_2__c, 
                                                       competitor_3__c, Competitor_Price_1__c,
                                                       Competitor_Price_2__c, Competitor_Price_3__c,
                                                       Best_Competitor_Price__c,Best_Competitor__c 
                                                       from opportunity 
                                                       where id in :trigger.Newmap.keySet()]);

    //process the record one by one and assign to the new list
    Decimal LowestPrice;    
    Decimal CurrentPrice;
    String CompName;

    for(Id i : m.keySet()){
     List<Decimal> AllPrices = new List<Decimal>();
	// System.debug('Values of AllPrices ' + AllPrices);
     List<String> AllComps = new List<String>();

     AllPrices.add(m.get(i).Competitor_Price_1__c);
	 AllPrices.add(m.get(i).Competitor_Price_2__c);
     AllPrices.add(m.get(i).Competitor_Price_3__c);

     AllComps.add(m.get(i).Competitor1__c);
     AllComps.add(m.get(i).Competitor_2__c);
     AllComps.add(m.get(i).Competitor_3__c);
	
    //compare each competitor's price with the LowestPrice and update if competitor's price is less
    for(Integer l; l < AllPrices.size(); l++)
        {
           CurrentPrice = AllPrices.get(l);
	            if(CurrentPrice < LowestPrice)
		            {
		                LowestPrice = CurrentPrice;
		                CompName = AllComps.get(l);
		            }

        }
    //update Best Competitor and Best Competitor Price fields    
    m.get(i).Best_Competitor_Price__c = LowestPrice;
    m.get(i).Best_Competitor__c = CompName;
	}
}
The problem is I keep getting a null values in AllPrices and AllComps lists and the update doesn't happen. The code compiles fine though. Please help...
 
Best Answer chosen by Mark Z Dean
Santosh Bompally 8Santosh Bompally 8
Also if i'm not wrong, your query returns null for before insert scenario, because the records are not inserted into the DB yet, and in before update it considers the old values. hence, practicing maps with this scenario may be the best idea. it would rathar lead to confusion. 

However, if you still want this to be errorless, Change the trigger to After insert and After Update and update the changes into the database. 

All Answers

Santosh Bompally 8Santosh Bompally 8
Hi Mark, 
Always initiate values when you're running a comparison loop. you initial soql is not needed in trigger. try this code. 
 
trigger CompetitorPrice5 on Opportunity (before insert, before update) {


    Decimal LowestPrice;    
    Decimal CurrentPrice;
    String CompName;

    for(Opportunity o : trigger.new){
     List<Decimal> AllPrices = new List<Decimal>();
     List<String> AllComps = new List<String>();

     AllPrices.add(o.Competitor_Price_1__c);
	 AllPrices.add(o.Competitor_Price_2__c);
     AllPrices.add(o.Competitor_Price_3__c);

     AllComps.add(o.Competitor1__c);
     AllComps.add(o.Competitor_2__c);
     AllComps.add(o.Competitor_3__c);
	 
	 // Initiate values
	 
	 LowestPrice = o.Competitor_Price_1__c ;
	 CompName = o.Competitor1__c ;
	 
    //compare each competitor's price with the LowestPrice and update if competitor's price is less
    for(Integer l=0; l < AllPrices.size(); l++)
        {
           CurrentPrice = AllPrices.get(l);
	            if(CurrentPrice < LowestPrice)
		            {
		                LowestPrice = CurrentPrice;
		                CompName = AllComps.get(l);
		            }

        }
    //update Best Competitor and Best Competitor Price fields    
    o.Best_Competitor_Price__c = LowestPrice;
    o.Best_Competitor__c = CompName;
	}
}



 
Mark Z DeanMark Z Dean
Thanks Santosh...I should have mentioned that I was trying to use map in the code just so I could learn it. Can you help with my piece of code on how that would work with using a map.
Santosh Bompally 8Santosh Bompally 8
Hi Mark, 

In your code, in line 30 , initiate the values. 

paste these 2 lines. 
​ // Initiate values
 LowestPrice = m.get(i).Competitor_Price_1__c ; 
CompName = m.get(i).Competitor1__c ;
Thanks
Santosh Bompally 8Santosh Bompally 8
Also if i'm not wrong, your query returns null for before insert scenario, because the records are not inserted into the DB yet, and in before update it considers the old values. hence, practicing maps with this scenario may be the best idea. it would rathar lead to confusion. 

However, if you still want this to be errorless, Change the trigger to After insert and After Update and update the changes into the database. 
This was selected as the best answer
Mark Z DeanMark Z Dean
I see...for the before insert scenario, wouldn't the trigger.NewMap have values in it(line 11) because its a map of new values? 

Also I have got it to work now with your help, of couse, but the 2 fields in line 43 and 44 are not getting updated with the competitor price and name. Do you have any suggestions for that? I am sure I don't have to do an explicit insert DML, right? 
Mark Z DeanMark Z Dean
Map<id, Opportunity> m = trigger.NewMap;
I replaced the code from line 6-11 with above and its working fine. So the SOQL was not needed as you had implied earlier. Thanks for your help Santosh...
Mark Z DeanMark Z Dean
I spoke a bit too early...When I tried to insert a record, it kept failing because I was using NewMap which doesn't have an id until after a record has been inserted. Finally a few more Google searches and tweaks to the code have it working for both inserts and updates. Here is the final code with the hope that it may save sometime time in the future
trigger CompetitorPrice5 on Opportunity (before insert, before update) {

    Map<id, Opportunity> m = new map<Id, Opportunity>();

    //select all records into a map
    if(trigger.isBefore){
        if(trigger.isInsert || trigger.isUpdate){
            for(Opportunity o : trigger.new)
            {
                m.put(o.id, o);
            }
                       
        }
        
    }
    
    //process the record one by one and assign to the new list
    Decimal LowestPrice;    
    Decimal CurrentPrice;
    String CompName;

    for(Id i : m.keySet()){
     List<Decimal> AllPrices = new List<Decimal>();
     List<String> AllComps = new List<String>();
        
     AllPrices.add(m.get(i).Competitor_Price_1__c);
	 AllPrices.add(m.get(i).Competitor_Price_2__c);
     AllPrices.add(m.get(i).Competitor_Price_3__c);
	 System.debug('Values of AllPrices ' + AllPrices);

        
     AllComps.add(m.get(i).Competitor1__c);
     AllComps.add(m.get(i).Competitor_2__c);
     AllComps.add(m.get(i).Competitor_3__c);
     System.debug('Name of Companies i.e. AllComp ' + AllComps);

        
     LowestPrice = m.get(i).Competitor_Price_1__c ;
	// CompName = m.get(i).Competitor1__c ;
   System.debug('Lowest price ' + LowestPrice);
        
        
    //compare each competitor's price with the LowestPrice and update if competitor's price is less
    for(Integer l=0; l <  AllPrices.size(); l++)
        {
           System.debug('Size of the list is ' + AllPrices.size());

           CurrentPrice = AllPrices.get(l);
           System.debug('Lowest price in for loop ' + CurrentPrice);

	            if(CurrentPrice <= LowestPrice)
		            { 
		                LowestPrice = CurrentPrice;
		                CompName = AllComps.get(l);
                        System.debug('Lowest price in If Condition' + LowestPrice);

		            }

        }
    //update Best Competitor and Best Competitor Price fields  
    //System.debug('Competitor Price ' + LowestPrice);  
    m.get(i).Best_Competitor_Price__c = LowestPrice;
    System.debug('Competitor Price 123' + m.get(i).Best_Competitor_Price__c);  

    m.get(i).Best_Competitor__c = CompName;
        
   System.debug('Competitor Name is, tada ' + m.get(i).Best_Competitor__c);  
    
	}
}
Santosh Bompally 8Santosh Bompally 8
Hi Mark, 
Good to know that you cracked this and hope you have a good understanding on Maps now. 
Cheers. 
 
Ajay K DubediAjay K Dubedi
Hi Mark,

I have updated your code with a small change. Please share if this works for you.

trigger CompetitorPrice5 on Opportunity (before insert, before update) {

    Set<Id> oppIdSet = new Set<Id>();
    Map<id, Opportunity> BestPriceM = new Map<id, Opportunity>();
    
    for (Opportunity oOpportunity : trigger.new) {
        oppIdSet.add(oOpportunity.id);
    }

    //select all records into a map
    Map<id, Opportunity> m = new Map<id, Opportunity>([select id, competitor1__c, competitor_2__c, 
                                                       competitor_3__c, Competitor_Price_1__c,
                                                       Competitor_Price_2__c, Competitor_Price_3__c,
                                                       Best_Competitor_Price__c,Best_Competitor__c 
                                                       from opportunity 
                                                       where id in :oppIdSet]);

    //process the record one by one and assign to the new list
    Decimal LowestPrice;    
    Decimal CurrentPrice;
    String CompName;

    for(Id i : m.keySet()){
     List<Decimal> AllPrices = new List<Decimal>();
    // System.debug('Values of AllPrices ' + AllPrices);
     List<String> AllComps = new List<String>();

     AllPrices.add(m.get(i).Competitor_Price_1__c);
     AllPrices.add(m.get(i).Competitor_Price_2__c);
     AllPrices.add(m.get(i).Competitor_Price_3__c);

     AllComps.add(m.get(i).Competitor1__c);
     AllComps.add(m.get(i).Competitor_2__c);
     AllComps.add(m.get(i).Competitor_3__c);
    
    //compare each competitor's price with the LowestPrice and update if competitor's price is less
    for(Integer l; l < AllPrices.size(); l++)
        {
           CurrentPrice = AllPrices.get(l);
                if(CurrentPrice < LowestPrice)
                    {
                        LowestPrice = CurrentPrice;
                        CompName = AllComps.get(l);
                    }

        }
    //update Best Competitor and Best Competitor Price fields    
    m.get(i).Best_Competitor_Price__c = LowestPrice;
    m.get(i).Best_Competitor__c = CompName;
    }
}

Thank You,
Ajay Dubedi