1

I'm creating new records in my LWC and have a map to allow for updating values before doing the save and I finally got the LWC to communicate with the controller, but the values sent seem to be empty, so I'm not sure where things are going wrong. I tried with jsonData:this.mapOfFields and with answers:this.mapOfFields but neither works.

JS:

import saveAnswers from "@salesforce/apex/QuestionnaireAnswerController.SaveAnswers";

@track mapOfFields = [];


this.mapOfFields.forEach(function (answ) {
  console.log("create answer answ" + JSON.stringify(answ));
});

console.log("create answer answ" + this.mapOfFields);

saveAnswers({
  jsonData: this.mapOfFields
}).then((result) => {
  console.log("Answers saved: " + result);
});

If debug the JS I can see the map has values and the call to the controller completes as per the returned boolean.

enter image description here

Yet when I view the debug log from the Apex, it says the passed value is empty. How should I pass and how should I receive, since this isn't working?

Apex:

@AuraEnabled(cacheable=true)
public static boolean SaveAnswers(List<Map<String, String>> answers) {
    System.debug(
      '####QuestionnaireAnswerController SaveAnswers ' + answers.size()
    );
    for (Map<string, String> answer : answers) {
      for (String qa : answer.keySet()) {
        System.debug(
          '####QuestionnaireAnswerController SaveAnswers answer: ' +
          answer.get(qa)
        );
      }
    }
    return true;
}

enter image description here

1
  • How is it all working for you now? Apr 3, 2023 at 18:03

1 Answer 1

1

You need to pass the an equivalent datatype from LWC to Apex.

  • From LWC you are passing an Array called jsonData

  • Into Apex you are receiving a Map<String,String> called answers

Both the name and datatype need to match.

Either pass a map (javascript Object) - and call it answers

OR

Receive an Array from into Apex - and call keep the name answers


I'm going with option 2 because there is no good reason to be passing a Map.

Javascript:

//rename your variable, because it's an array, not a map
@track answersArray = []; 

saveAnswers({ answersJSON: JSON.stringify(this.answersArray)})
.then((result) => {});

Apex:

@AuraEnabled //remove cacheable
public static boolean SaveAnswers(String answersJSON) {
  Answer[] answers = (Answer)JSON.deserialize(answersJSON,Answer[].class);
  for (Answer answer : answers){
    System.debug('####QuestionnaireAnswerController SaveAnswers answer: ' + answer.key + ' ' + answer.value);
  }
  return true;
}

public class Answer{
  public String key {get;set;}
  public Question_Answer__c value {get;set;}
}

OK... take two. This is probably the simplest approach:

You have an array with objects containing parameters key and value. Extract the object named value into an array to send to Apex.

let answers = answersArray.map( answer=>answer.value);
saveAnswers({ answersJSON: JSON.stringify(answers)})
.then((result) => {});

Your Apex method becomes much simpler as we don't need a custom data type:

@AuraEnabled 
public static Boolean SaveAnswers(String answersJSON) {
  Question_Answer__c[] answers = (Question_Answer__c)JSON.deserialize(answersJSON,Question_Answer__c[].class);
  for (Question_Answer__c answer : answers){
    System.debug('####QuestionnaireAnswerController SaveAnswers answer: ' + answer.key + ' ' + answer.value);
  }
  return true;
}
11
  • I've changed the LWC call to 'answers: this.mapOfFields' , but am getting an 'uncaught' error in the js debug now. I don't quite know what to change where. How do I make the JS side an object, or what do I change on the apex side?
    – Irene
    Apr 3, 2023 at 4:48
  • I'm getting this error after making the changes you suggested. It seems to think there's only one, not multiple records: "List<QuestionnaireAnswerController.Answer> answers Illegal assignment from QuestionnaireAnswerController.Answer to List<QuestionnaireAnswerController.Answer> "
    – Irene
    Apr 3, 2023 at 5:28
  • It was still not happy. I did some searching and found the line had to be as this: "Answer[] answers = (Answer[]) JSON.deserialize(answersJSON, Answer[].class);". I thought yay! Except when I then tested I got an error "System.NullPointerException: null input to JSON parser". I have a console.log right before the call to Apex and it definitely contains values, yet when it gets into the apex class it appears to be null. I added a debug to display the passed string and this is what it shows: [119]|DEBUG|####QuestionnaireAnswerController SaveAnswers answersJSON: null
    – Irene
    Apr 3, 2023 at 21:18
  • In my JS I added: " console.log("JSON array: " + JSON.stringify(this.mapOfFields)); saveAnswers({ answers: JSON.stringify(this.mapOfFields) }).then( " and the js debug displays the content just before the call: " JSON array: [{"key":"a28p0000000XifnAAC","value":{"RecordTypeId":"012p0000000G9mXAAS","Question_Number__c":2,"Related_Question__c":"a28p0000000XifnAAC","Requires_File_Upload__c":false}},{"key":"decl","value":{"RecordTypeId":"012p0000000G9mXAAS"
    – Irene
    Apr 3, 2023 at 21:24
  • 1
    Yes, I thought you meant Javascript objects, not sObjects. New answer at bottom. Apr 4, 2023 at 5:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .