0

Expansion to original question: Error: Future method cannot be called

Need to remove record variable from reference. Can someone help me and explain the process?

Error:

Error: Compile Error: Variable does not exist: post at line 11 column 13

class:

public class myclass
{
    static Boolean shouldProcessAsync()
    {
        return !system.isFuture() && !system.isBatch() && !system.isQueueable() &&
            Limits.getLimitFutureCalls() > Limits.getFutureCalls();
    }

    public static void POST(string url, string body)
    {
        if (record.isEmpty()) return;

        if (shouldProcessAsync())
        {
            post(url, body);
        }
        else
        {
            // logic
        }
    }
    @future(callout=true)
    static void POSTAsync(Set<Id> recordIds)
    {
        POST([
            SELECT Name
            FROM Account
            WHERE Id IN :recordIds
        ]);
    }
}

2 Answers 2

1

The issue you have, and the issue you think you have, are two different things. You actually have a few different issues in this code.

I think that you've probably paraphrased your code here, but you've omitted some important details. That, or you haven't copied and pasted the error message that you're getting word-for-word. If you're going to make changes to your code when sharing it here, you need to be making those changes consistently (else you run the risk of confusing people, like you have here).

I vaguely recall seeing the shouldProcessAsync() method as an answer to another question. If you're asking a new question based on things you did from another question, you really should be providing that context.

Anyway, getting to the issues...

record is not defined anywhere

The error you're getting is very straightforward. Setting aside the mismatch between your code and your error message, line 11 is if(record.isEmpty()) return;

Take a look at your code. I don't see a declaration for a record or post variable anywhere. It's also not one of your method arguments.

No declaration = no variable. If you try to use a variable that doesn't exist, you'll get a "variable does not exist" error. Pretty simple.

Getting rid of the error is a simple matter. Declare your variable somewhere (in the method, as a class variable, make it an argument to your POST() method).

The gotcha here if you make this a class variable is that it would need to be a static variable. Static methods can make use of static class variables only. Non-static methods can make use of instance (non-static) class variables as well as static class variables.

Your call to isEmpty() suggests that this should be a collection of some sort.

The above would fix the syntax of your code, but not the semantics. You'll need to figure out how to make record.isEmpty() not be true (or change that code or change its location), or you'll never do any work. Fixing the semantics is out of scope for this question and, even if it weren't, you haven't provided enough context to make any suggestions here.

Your call to your async method is wrong

Or rather, you aren't calling it at all.

The next lines, after your error, are

if (shouldProcessAsync())
{
    post(url, body);
}

The if statement here indicates that you do want to go async, but then you go and recursively call the POST() method instead. You should be calling POSTAsync() here.

Your @future method is passing the wrong parameters back to POST()

Look at the method signature for POST().

It takes two strings.

Now take a look at your @future method.

It's trying to pass a List<Account> to POST().

A List<Account> is not the same as two Strings. This will cause an error.

Parting words

One thing that's probably not an issue is your switching between POST() and post(). Most (if not all) identifiers, including method names, are case-insensitive in Apex.

It does, however, make things more confusing when you switch between capitalization styles. You can continue to call your method like post(), but that's not great practice. Pick a style, and stick with it.

I think this is a good demonstration of what happens when you copy & paste code from others without understanding what it does or how it fits in with your existing code.

You need to go back and evaluate what you're trying to do here. Once you have your base code (i.e. your basic callout logic/processing) in a compilable state, and write good unit tests to exercise the behavior, you can move on to trying to understand and integrate asynchronous operation into that.

Trying to change too many things at once is as bad for programming as it is for science.

3
  • +1 - for reference the source is a slightly confused adaptation of Adrian's answer here.
    – David Reed
    Jan 17, 2019 at 14:50
  • @DerekF can I chat with you? Adrian helped me out a lot.
    – user56320
    Jan 17, 2019 at 21:27
  • @HUBBY0716 not right at this moment. I'm leaving from work and won't be available for the rest of the afternoon/evening/night.
    – Derek F
    Jan 17, 2019 at 21:44
0

There are two problems here, which are related to syntax.

  1. Record is not defined anywhere, you can remove it directly
  2. Parameter passed to POST() on line 25 is incorrect, if you wish to pass list of account to this, then you need to change its parameters to Account[] accList, or either way you need to pass parameters according to its current definition.
  3. Recursive call post(url, body); on line 15 seems unwanted.
0

You must log in to answer this question.