1

For some reason, my code won't compile and I'm not entirely sure why.

The method accepts the following arguments

public static void doSomething(Map<Id, Order> oldMap, List<Order> orderList) {}

And I'm providing the following arguments from my trigger handler as such:

public void beforeUpdate(Map<Id, SObject> newItems, Map<Id, SObject> oldItems) {
    List<Order> orderList = (List<Order>) newItems.values();
    ClassName.doSomething(oldItems, orderList);
}

Which gives me the error

Method does not exist or incorrect signature: void doSomething(Map<Id,SObject>, List<Order>) from the type ClassName

However, using Trigger.oldMap and Trigger.new works fine and compiles as expected:

ClassName.doSomething(Trigger.oldMap, Trigger.New);

Trigger.new is identical to List<Order> orderList = (List<Order>) newItems.values();

and Trigger.oldMap is identical to Map<Id, SObject> oldItems

What am I doing wrong here?

  • can you please try your arguments be like public void beforeUpdate(Map<Id, SObject> newItems, Map<Id, SObject> oldItems) {...} – Navii May 14 at 9:41
2

You are getting this error because you are trying to pass an instance of Map<Id, sObject> where it expects it to be of type Map<Id,Order> i.e. it expects the concrete type.

So, like you are typecasting List<sObject> to List<Order>, you will also have to typecast Map<Id,sObject> to Map<Id,Order>.

Although this typecasting is not as straight forward but it is doable using Map methods like below

Map<Id, Order> mapOrders = new Map<Id, Order>((List<Order>)oldItems.values());

So, here a Map<Id,sObject> is typecast ed to Map<Id,Order> using below steps in single line

  1. Get values from oldMap using values() method of Map which will return List<sObject>
  2. Typecast it to List<Order>
  3. And then use Map<ID,sObject>(recordList) constructor of map which takes List<Order> to construct Map<Id,Order>

So your code should look like this

public void beforeUpdate(Map<Id, SObject> newItems, Map<Id, SObject> oldItems) {
    List<Order> orderList = (List<Order>) newItems.values();
    Map<Id, Order> mapOrders = new Map<Id, Order>((List<Order>)oldItems.values());
    ClassName.doSomething(mapOrders, orderList);
}
| improve this answer | |
  • Thanks a lot for the explanation. I just find it weird that I didn't need to type cast when using Trigger.oldMap and Trigger.new - but with these I do? – erikvm May 14 at 10:54
1

Problem is that you are passing in first parameter a Map<Id, Order> and it excepts a Map<Id, SObject> Map<Id, Order> cannot be casted in implicit way from Map<Id, SObject> These types are not in same hierarchy, so Map<Id, Order> is not extending Map<Id, SObject> like its for eg. pair SObject -> Account

Trigger.oldMap compiles because types (proveded and excepted) are the same. To make it work I would suggest to make method parameters more specific (use Order instead of SObject).

| improve this answer | |
  • So how should I cast it from Map<Id, SObject> to Map<Id, Order>? Because just looking at the logs, isn't Trigger.oldMap dynamically cast from Map<Id, SObject> to Map<Id, Order>? – erikvm May 14 at 9:44
  • Yes, exactly, when you cast it before passing to function it should start compiling properly – patryk May 14 at 9:46
  • So what is the solution? – erikvm May 14 at 10:06
  • Cast to proper type before passing Map to a fucntion, or change signature of funtcion that the types would correct after. – patryk May 14 at 11:40

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.