"Limit expression must be of type Integer" error when using Apex variable in SOQL

Its very clear that Bind expression do work .

To test this I invoked the static method simply from the developer console and it worked .

TestAccountCtrl.returnAccountsAsTest(5);

This made me suspect that this has to do with lightning component variable not getting passed as the integer as it should be .

Also specifically it has to do only when we have design file attribute mapped to the attribute of component .I feel its a bug within SFDC and needs to forwarded to lightning components team as docs clearly do mention that integer is supported in design file .

Here is another weird observation .I just changed the type of your attribute to String and it does work .

<aura:component implements="force:appHostable" controller="TestAccountCtrl">
<aura:attribute name="limitAmount" type="String" default="5"/>
<aura:attribute name="accountlst" type="Account"/>
<aura:handler name="init" value="{!this}" action="{!c.retrieveAccounts}" />
<div>
    <ul>
     <aura:iteration items="{!v.accountlst}" var="acc">
            <li>{!acc.Id}</li>
     </aura:iteration>
    </ul>
</div>

I came up with workaround solution if you still want to keep type as Integer and it works is as below

<aura:component implements="force:appHostable" controller="TestAccountCtrl">
<aura:attribute name="limitAmount" type="Integer" default="5"/>
<aura:attribute name="accountlst" type="Account"/>
<aura:handler name="init" value="{!this}" action="{!c.retrieveAccounts}" />
<div>
    <ul>
       <aura:iteration items="{!v.accountlst}" var="acc">
            <li>{!acc.Id}</li>
        </aura:iteration>
    </ul>
</div>

The modified controller code

public with sharing class TestAccountCtrl {

@AuraEnabled
public static List<Account> returnAccountsAsTest(Integer amount) {
    Integer liamount = integer.valueof(amount);
    List<Account> accounts = [SELECT Id FROM Account LIMIT : liamount];
    return accounts;
}

}

In case you need helper file for reference ,here is below

 ({
 "retrieveAccounts" : function(cmp) {
    var action = cmp.get("c.returnAccountsAsTest");
    action.setParams({ amount : cmp.get("v.limitAmount") });

    action.setCallback(this, function(response) {
        // process state here
    cmp.set("v.accountlst", response.getReturnValue());

    });
    $A.enqueueAction(action);
  }
})

This is just work around and I am sure this is a bug in SFDC lightning components .Let me file a bug with support .

Latest update:::

I reached out to the lightning component team and they have confirmed its bug in the serializer .I will be opening a case with them and hopefully they fix it.


Since I don't see the issue immediately, let's try and debug this: Within your apex controller method returnAccountsAsTest, limitAmount is declared as an integer parameter, so it must be an int. However, integer variables can contain null, which would imply that your js controller is not passing the limit value correctly. To test, try adding the following as the first line of returnAccountsAsTest, just before the SOQL query:

System.AssertNotEquals(null, limitAmount);

If limitAmount is null when the method is invoked, the assertion will throw an uncatchable exception, which should be pretty easy to spot. In that case, you'll need to backtrack how you are invoking the method from the JS controller, perhaps with some console logging.

If the assertion does NOT fail, then the only thing that makes sense is that the bind simply isn't working as advertised; I'd test it by temporarily removing any doubt about the param:

@AuraEnabled
public static List<Account> returnAccountsAsTest(Integer limitAmount) {
    integer tempLimit = 5;
    List<Account> accounts = [SELECT Id FROM Account LIMIT :tempLimit];
    return accounts;
}

If this version also throws the same exception, I'd call it conclusive proof that you can't use a bind var in a limit clause, and I'd switch to using dynamic SOQL. I'd also consider opening a case if you can, since the docs clearly state that it should work, and you'd have a nice, small, reproducable test case for support to work with.