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.

  • What is the compiler complaining about ? – Jarvis Aug 17 '18 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 '18 at 13:59
  • @Daryn do you need to create a set of contact ids within the loop? – Jayant Das Aug 17 '18 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 '18 at 18:38
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
  • Thanks I will not be able to try this out until I return to office but I will definitely try it. – Daryn Aug 17 '18 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();
  • 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 '18 at 18: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.