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?

  • Check if System.debug(limitAmount instanceof Integer) returns true – Moshe Karmel Feb 8 '16 at 15:40
  • It appears to me as though at some point the integer is being cast to a string which means you need to cast it back to an integer before you can use it as an integer for your purposes. – crmprogdev Feb 8 '16 at 15:50
  • I didn't think you could merge in LIMIT values. I thought you had to go the dynamic route. – Adrian Larson Feb 8 '16 at 16:00
  • 1
    @AdrianLarson I was thinking the same thing, but the Apex Docs list Limit clause as a valid bind use: developer.salesforce.com/docs/atlas.en-us.apexcode.meta/… – Jason Clark Feb 8 '16 at 16:02
  • 1
    @MosheKarmel it won't let me check since it claims that an instance of an integer is always an instance of an integer. – Matthew Green Feb 8 '16 at 16:33
up vote 10 down vote accepted

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.

  • Thanks for the workaround and the update on the bug. If you get a link to the bug report I would be interested in following it. – Matthew Green Feb 9 '16 at 14:40

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.

  • 1
    I have similar logging and code attempt in my copy and both work without issues. I can see in the logs that it's an Integer with a value of 15 and the local variable works without issues. So there is something specific to that parameter variable not being able to bind. I've updated the question to try and make clearer some things I've tested and seen. – Matthew Green Feb 8 '16 at 16:40
  • 1
    Looks like SFDC bug to me . – Mohith Shrivastava Feb 8 '16 at 17:07
  • 2
    @MohithShrivastava I'm new enough to all of the Salesforce coding I assumed I missed something but I'm thinking this might be the case more and more. – Matthew Green Feb 8 '16 at 17:28
  • @MatthewGreen I cant agree more .Ability to limit the no of cards on community builder is much needed .Let me do my bit of homework on this – Mohith Shrivastava Feb 8 '16 at 17:30
  • @MatthewGreen You said in comment, "the local variable works without issues," by which I assume you mean something like my second code snippet above... have you tried assigning the local variable from the param, e.g., integer tmpLimit = limitAmount;? – Jason Clark Feb 8 '16 at 18:03

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.