[SalesForce] “Limit expression must be of type Integer” error when using Apex variable in SOQL

I'm building a simple Lightning Component that pulls in a set amount of accounts and displays them. However, I keep getting a Limit expression must be of type Integer error message. I've hard-coded a number and set a variable to use in the SOQL with neither giving this error but for some reason the value being passed in is the only way that gives this error.

Here is the various pieces of code:

Apex

public with sharing class TestAccountCtrl {

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

I've also done the following in the Apex controller and all work without issues:

List<Account> accounts = [SELECT Id FROM Account LIMIT 15];

Integer amount = 15;
List<Account> accounts = [SELECT Id FROM Account LIMIT :amount];

String query = 'SELECT Id FROM Account LIMIT ' + limitAmount;
List<Account> accounts = Database.query(query);

Below is the rest of the code.

Component

<aura:component implements="forceCommunity:availableForAllPageTypes" controller="TestAccountCtrl">
    <aura:attribute name="limitAmount" type="Integer" default="5" />
    <aura:handler name="init" value="{!this}" action="{!c.retrieveAccounts}" />
</aura:component>

Design

<design:component label="Knowledge Articles">
    <design:attribute name="limitAmount" label="Limit Amount" default="5" />
</design:component>

Controller

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

        action.setCallback(this, function(response) {
            // process state here
        });
        $A.enqueueAction(action);
    }
})

Logging shows that limitAmount is an Integer with a non null value (15 in my tests). I'm not sure why it thinks the value I'm passing into the Apex function is not an integer. Is there something I'm missing in all of this?

Best Answer

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.