-2

Is it possible to pass a JavaScript object to Apex controller in lightning?

Here is what I tried:

@AuraEnabled
public static void changeProgram(Object info) {
    update new zced__Training_Program__c(
      Id = info.Id
    );
}

I am getting the error:

Variable does not exist: Id

enter image description here

I believe I am getting this because Object in Apex and object in JavaScript are different things.

So, I found that there is such a thing called JavaScript Map and there are a lot of examples how to pass it from client-side controller to server-side. And I am feeling it can easily substitute the JavaScript object, but still I would like to know for sure whether or not it is possible.

I am only interested in the Apex part.

0

3 Answers 3

7

Apex is strongly typed, which means that it has to know in advance what type of data it's dealing with. In this specific case, you could have just passed in an Id:

public static void changeProgram(Id recordId) {

In the more general sense, you can pass in a Map, which is as close as you get to a JavaScript object:

public static void changeProgram(Map<String, Object> info) {
  update new zced__Training_Program__c(
    Id = (Id)info.get('Id')
  );
}

Or, perhaps more preferentally, you can pass in an entire sObject:

public static void changeProgram(zced__Training_Program__c record) {
  update record;
}

But that requires altering the JavaScript parameter to match; the object has to have the correct type:

action.setParams({ record: { sobjectType: 'zced__Training_Program__c', Id: 'somerecordid' }});
1
  • Oh. Yeah, I knew the last approach. Actually it works even without setting the sobjectType.
    – iloveseven
    Aug 23, 2018 at 18:48
3

You can create a JSON String of your object and pass to apex Controller. The input param in apex method can be a string which you can deserialize.

var action = component.get("c.changeProgram");

action.setParams({  param1: JSON.stringify(object)});// setting the parameter to apex class method

Apex:

@AuraEnabled
public static void changeProgram(String param1) {
   // deserialize your string

}
1
  • Could you, please, provide an example of actually accessing the sent data in Apex?
    – iloveseven
    Aug 23, 2018 at 18:46
2

To build on Anurag A's answer, you can create a JSON String of your object in your JS controller using JSON.stringify() and pass it as a String variable to your Apex controller. Then you can use Apex's JSONParser to parse the key-value pairs into a Apex Map (which is different from a JS map because reasons) like so:

var jsObject= { key1 : value1 , key2 : value2};
var packagedString = JSON.stringify(jsObject);

...and then pass them to your Apex controller using the standard code (https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/controllers_server_actions_call.htm).

In your Apex method, you can then unpackage the map using the following code:

Map<String, String> unpackedMap = new Map<String, String>();
String tempKey, tempValue;

//Unpack the packaged JSON string. Use the JSONParser class to read the JSON 
//string, iterate over and extract each Key 
//and associated value and send it to our Apex map.
JSONParser parsedMap = JSON.createParser(jsonStringFromJavascript);
while(parsedMap.nextToken() != null) {
    if(parsedMap.getCurrentToken() == JSONToken.FIELD_NAME) {
        tempKey = parsedMap.getText();
        parsedMap.nextToken();
        tempValue = parsedMap.getText();
        unpackedMap.put(tempKey, tempValue);
    }
}
//Will return the value associated with key1
system.debug(unpackedMap.get('key1'));

This has the benefit of allowing you to stuff any data into the JSON string, not just data that is associated with an SObject.

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.