0

The ws_contact_callout class expects a SET of ids. in the Execute methods I attempt to get it but within the loop but the compiler is complaining.

How can/should I get the Set of ids without requery?

public class sync_mdm_contact_batch_V2 implements Database.Batchable<sObject>, 
                                              Database.Stateful , Database.AllowsCallouts
{
 public integer recordCount = 0;

 public Database.QueryLocator start (Database.BatchableContext bc)
 {
    return Database.getQueryLocator('SELECT Id FROM Contact WHERE RecordType.DeveloperName = \'xxx\'');
 }

 public void execute(Database.BatchableContext bc, List<Contact> scope)
 {
    //variable does not exist: records
    Set<Id> ids = new Map<Id, Contact>(records).keySet();

    //process each batch of contacts
    for (id recordid : ids)
    {
        //method does not exist on incorrect signature:  void future_callout(id) from the type ws_mdm_contact
        //Signature for ws_mdm_contact.future_callout(Set<ID> ids)
        ws_mdm_contact.future_callout(recordid);

        //increment recordsProcessed
        recordCount += ids.size();
    }
 }

 public void finish(Database.BatchableContext bc)
 {
    system.debug(recordCount + 'records processed');

    AsyncApexJob job =
        [   SELECT Id, Status, NumberOfErrors, JobItemsProcessed, TotalJobItems, CreatedBy.Email
            FROM AsyncApexJob
            WHERE Id = :bc.getJobId()
        ];
    //email
    emailManager.sendMail('email', 'subject', string.valueof(recordCount));
 }
}

This is my first attempt at a batch class following the trailhead example with a twist. In the Execute method I want to be able to send 100 records (set of ids) to my class which does my callouts. If I rightly understand things I can have up to 100 callouts. So this should get me 100 records x 100 callouts aka 10000 records.

reported issue:

Getting closer I can almost taste it. I updated the code to reflect current state and commented where it is complaining. The endpoint is constructed to only handle one record at time so I think I need to do the loop vs a bulkcall.

4
  • What is the compiler complaining about ?
    – Jarvis
    Aug 17, 2018 at 13:45
  • Invalid initializer type Contact found for Map<Id,Contact>: expected a Map with the same key and value types, or a valid SObject List and Variable does not exist: contactMap
    – Daryn
    Aug 17, 2018 at 13:59
  • @Daryn do you need to create a set of contact ids within the loop?
    – Jayant Das
    Aug 17, 2018 at 15:34
  • I think the querylocator gets me the qualified list of contacts. Signature for ws_mdm_contact.future_callout(Set<ID> ids). So I am thinking I need to take the results which looks like forces into List<Contact> and convert that into a Set that the callout class is expecting.
    – Daryn
    Aug 17, 2018 at 18:38

2 Answers 2

1

You should be able to create a set of ids within the loop in the following way.

Set<Id> contactIds = new Set<Id>();
for (Contact C : scope) {
    contactIds.add(c.Id); // this is what you need here to add the contact ids
    //increment recordsProcessed
    recordsProcessed ++;
}

ws_contact_callout(contactids); // perform other operation only after you have added the ids in the loop
1
  • Thanks I will not be able to try this out until I return to office but I will definitely try it.
    – Daryn
    Aug 17, 2018 at 20:04
0

If you want to get all the ids, make one callout per, then increment your record count:

Set<Id> recordIds = new Map<Id, Contact>(scope).keySet();
for (Id recordId : recordIds)
{
    // make callout
}
recordCount += recordIds.size();

Original Explanations Below

You need to pass in the entire scope to your constructor. It accepts a collection (List<SObject>), not a single record (SObject).

Incorrect

for (Contact record : records)
{
    Set<Id> ids = new Map<Id, Contact>(record);
}

Correct

Set<Id> ids = new Map<Id, Contact>(records).keySet();

If you need to pass each Id individually to your callout, you can loop over the collection:

for (Id recordId : ids)
{
    makeIndividualCallout(recordId);
}

Otherwise you can just make one call:

makeBulkCallout(ids);

And finally, you can simply increment your count by the size of the collection:

recordCount += ids.size();
1
  • reported issue: Getting closer I can almost taste it. I updated the code to reflect current state and commented where it is complaining. The endpoint is constructed to only handle one record at time so I think I need to do the loop vs a bulkcall.
    – Daryn
    Aug 17, 2018 at 18:40

You must log in to answer this question.

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