8

We have one dev org(without namespace) and one packaging org(with namespace) for developing lightning app. We are trying to access custom field in Lightning helper method as expence__c. It works fine in dev org. But in managed package response returned from the server controller prefixes namespace to given field as namespace__expence__c.

Code tries to access field expence__c which in turn gives field undefined error.

We can't hardcode namespace in code as it won't work in dev org.

We found two solution to this.

  1. Add/Remove namespace to field depending on org in Lightning code. (not preferred)

  2. Write DTO(data transfer object) class for all objects which we wish to use in Lightning. (need to create multiple DTO classes for those objects)

What is the best way to handle given problem.

  • Can you use c__expense__c? I don't know if that would work at all, just a thought. – Kris Gray Nov 29 '16 at 6:17
  • @KrisGray sorry given solution is not working in dev org. As apex controller returns field as expence__c and js code is trying to access as c__expence__c. Thinks of it as js object where expenc__c field is key in expense object and you are trying to access key with/without prefixes. In dev org there is no prefix in key so it won't work and will throw key undefined error. – Soham Nov 29 '16 at 7:08
  • @KrisGray This is a known limitation which adds pain to adopt lightning for managed package apps . – Mohith Shrivastava Nov 29 '16 at 10:18
  • @MohithShrivastava pls check this passing-complex-structured-data-type-from-lightning-to-apex I'm getting same kind of salesforce internal error while passing wrapper class to controller. Why we need to serialize/deserialize, is this known bug? Code works fine for objects but not for classes. – Soham Nov 30 '16 at 14:28
  • Soham that's a bug as well – Mohith Shrivastava Nov 30 '16 at 14:32
6

Thats a current limitation of the platform .The Javascript file does not get namespace added unlike visualforce pages for managed package .

I wrote a blog post on this .

The best way would be to create a message layer or a wrapper class like your second approach and that avoids the problem .The only caveat is you end up writing bunch of classes .

0

@Mohith Shrivastava, there's a major caveat that I've discovered. In the wrapper class, you can't declare variables with __c. So it doesn't work with custom fields -- assuming your lightning controller/component are using the actual field names with the __c extension.

Am I missing something?

0

@MohithShrivastava, thanks for the link to your blog. I'm new to namespace/packaging, and having just implemented a namespace for the dev org I used to write my app, I've now broken all the code.

I very much appreciate the 3rd point of your summary: never hardcode the namespace into the bundle. So, I'm trying to understand your wrapper class solution. Let me see if I can correctly summarize it.

  1. Apex knows to adjust for the namespace, and returns namespace-prepended results.

Apex automatically accounts for the namespace, without modification. So if your Lightning component calls Apex to return a list of records with several fields, the @auraEnabled Apex method (which has no namespace specified on the fields in the SOQL query), "knows" to retrieve the fields with the namespace, and returns the namespace-prepended fields to the Lightning Component.

  1. Lightning Controllers DON'T know to adjust for the namespace.

So, the Javascript controllers get namespace-prepended fields back from Apex and don't know what do to with them. If it assigns them to ...

  1. Lightning Components DON'T adjust for the namespace.

Component markup might include {!v.MyObject.Message__c} but the aura attribute MyObject doesn't have a Message__c field. Instead, it has MyObject.myNamespace__Message__c.

So the smart (if somewhat labor-intensive) approach would be to create a way to strip the namespace from the field names before Apex returns it to the Javascript controller. Is that right?

If I'm understanding your wrapper class, it does very little except repackage the results of the SOQL search into an object with the original field names. Is that right?

Your code:

public with sharing class AccountTest{

   @AuraEnabled
   public static list<AccountWrapper> getlstacc(){
      list<AccountWrapper> lstWrapper = new list<AccountWrapper>();
      for(Account acc :[Select Id , Name , NumberofLocations__c from Account order by NumberofLocations__c limit 10]){
         AccountWrapper accWrap = new AccountWrapper();
         accWrap.Name = acc.Name;
         accWrap.noOfLocations = integer.valueof(acc.NumberofLocations__c);
         lstWrapper.add(accWrap);
      }
      return lstWrapper;
   }

}

So, for example, the line accWrap.Name = acc.Name is taking the automatically adjusted acc.namespace__Name and dropping it into accWrap.Name -- with no namespace. Then it returns that to the Lightning controller. Have I got that right?

It might be labor intensive, but no more so than trying to hardcode the namespace into the Lightning components.

Thanks again for the approach.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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