Code Completion for imported AuraEnabled apex methods in LWC Javascript Controllers

Issue #2202 resolved
Jason Clark created an issue

Note: I’m using WebStorm to host IC2, so I have full JS support available.

When calling an imported AuraEnabled apex method in an LWC javascript class, parameter help knows all of the params, but completion does not. Here’s an example:

// in Apex class RateCardController:
@AuraEnabled
public static RateCard cloneRateCardForOpportunity(Id originalRateCardId, Id opportunityId, String title) {
  // omitted
}

The above Apex method has three params. Next let’s import into an LWC JS Controller:

import cloneRateCardForOpportunity from '@salesforce/apex/RateCardController.cloneRateCardForOpportunity';

Code completion works great here, typing @salesforce quickly expands options and lets me pick my controller method. Now I want to call it from JS code. Note that when calling imported Apex methods from JS, all method params must be passed in a Javascript object, and the object key names must match the Apex param names. For example:

cloneRateCardForOpportunity({
  originalRateCardId: this.sourceId,
  opportunityId: this.opptyId,
  title: this.title}).then( result => {
    // omitted
  }).catch(e) {//...}

When I start typing this line, parameter hints show the three expected apex params, but completion won’t help me create them. It would be great if I could auto complete a placeholder object, like:

cloneRateCardForOpportunity({ originalRateCardId: x, opportunityId: x, title: x })

But if that isn’t possible, being able to autocomplete at least each param name would be useful. However, that doesn’t appear to be possible either. Here’s what I see when I try it:

Comments (5)

  1. Scott Wells repo owner

    Unfortunately this seems to be a limitation of the dynamic type inference capabilities of the underlying IDE. IC2 is already providing dynamic type information to the IDE’s JavaScript/TypeScript plugin about the parameters and return value of the imported @AuraEnabled method (using Apex-to-ES6 type translation as appropriate). The parameter info hints that you’re seeing are actually coming from the JetBrains functionality based on that provided information, so it knows the expected anonymous data type’s properties. It’s just not offering code completions based on that information.

    For example, here’s an @AuraEnabled Apex method that I created to play with this again:

        @AuraEnabled
        public static LWCDataTransferObject getSpecificDto(String stringValue, Boolean booleanValue) {
            ...
        }
    

    Here’s my import:

    import getSpecificDto from '@salesforce/apex/LWCDataTransferObject.getSpecificDto';
    

    And here’s the imperative invocation:

        getSpecificDto()
            .then((result) => {
            });
    

    IC2 provides function signature information to the IDE as follows:

    function({stringValue: string, booleanValue: boolean}): Promise<{stringField: string, doubles: number[], integers: number[], accountField: Account, contactsField: Contact[], recursiveField: *, booleanProperty: boolean, opportunitiesProperty: Opportunity[]}>
    

    and I can see all of that reflected in the IDE, both parameters and return type:

    Unfortunately I don’t get code completions for the properties from the IDE:

    So yes, I’ve basically just repeated what you said but with a bit more detail about what’s happening under the hood. However, let’s compare that to a physical function with a very similar declaration and how it behaves:

        /**
         * @param {{stringValue: string, booleanValue: boolean}} params 
         * @return {Promise<{stringField: string, doubles: number[], integers: number[], accountField: Account, contactsField: Contact[], recursiveField: *, booleanProperty: boolean, opportunitiesProperty: Opportunity[]}>} 
         */
        getSpecificDto2(params) {
        }
    

    An invocation of that function looks virtually identical to the one above except that it has a deeper understanding of the parameter type:

    So, what does that mean? Well, it means that for this to work properly, I probably need to log a bug against JetBrains with the same info as above but also more information about exactly how I’m supplying the parameter info to their JS/TS type engine. I’ll plan to do that. It’s possible they’ll point out something I’m not doing quite right and I’ll be able to fix it on my end, but if memory serves, this was something I raised to them at the time and they agreed that it was a bug they needed to fix.

  2. Jason Clark reporter

    @Scott Wells Thanks for the detailed explanation, and the JB issue. Watched. Fingers crossed they can make it work, it would be a big time (and mistake) saver.

  3. Scott Wells repo owner

    I'm going to resolve this here and keep an eye on the JB issue. If it turns out that there's something I can/should do in IC2 itself, I'll reopen and use this to track that work.

  4. Scott Wells repo owner

    If you look at the linked JetBrains issue, a fix was just submitted for this problem. Not 100% sure when it will be delivered, but glad to see that they addressed it so quickly.

  5. Log in to comment