0

I am trying to bring some data from an API call to the salesforce UI with LWCs but I am struggling with where to start on it. I have a cls call out for it and some HTML added below. This is my first time working with payloads off of the platform or not doing SOQL queries to bring data to the front end. This is why I am a little confused on how to grab the data via JSON and then store the payload into object/objects to then render on the front end.

Controller.cls:

@AuraEnabled
public static Object retrievePhone(String parameter){
     Map<String,String> params = (Map<String,String>)JSON.deserialize(parameter, Map<String,String>.class);
     String phone = params.get('phone');
     String type = params.get('type');
     String user = params.get('user');
     String address = params.get('address');
     Http http = new Http();
     HttpRequest request = new HttpRequest();
     request.setEndpoint('callout:Endpoint');
     request.setHeader('Content-Type', 'application/json');
     request.setMethod('POST');
     JSONGenerator gen = JSON.createGenerator(true);
     gen.writeStartObject();
     gen.writeStringField('phone', phone);
     gen.writeStringField('type', type);
     gen.writeFieldName('user name');
     gen.writeStartObject();
     gen.writeStringField('user', user);
     gen.writeStringField('address', address);
     gen.writeEndObject();
     gen.writeEndObject();

     String body = gen.getAsString();
     request.setBody(body);
     Map<String, Object> res = new Map<String, Object>();
     try{
          HttpResponse response = http.seend(request);
          if(response.getStatusCode() == 200){
               res = (Map<String,Object>) JSON.deserializedUntyped(response.getBody());
               res.put('statusCode', response.getStatusCode());
          } else{
               //code for other responses here
               } catch(Exception ex){//exception handling here}
     return res;
     }
}

Html:

<template>
     <template for:each={userNumbers} for:item='userNumber'>
     <lightning-layout class="slds-border_bottom" key={userNumber.ID}>
          <lighting-layout-item flexibility="auto, no grow">
               <div class="custom-box">
               <lightning-radio-group name="radioGroup" options={options} value={value} type="radio"></lightning-radio-group>
               </div>
          </lighting-layout-item>
          <lighting-layout-item flexibility="auto" padding="around-small">
               <div class="custom-box">
                    <p>{userNumber.lastName}</p>
                    <p>{userNumber.address}</p>
                    <p>{userNumber.fullPhoneNumber}</p>
               </div>
          </lighting-layout-item>
     </lightning-layout>
     </template>
</template>

JavaScript:

nothing at the moment besides imports and get options function for radio button
3

The simplest way is to make sure you deserialize the JSON response into a custom Apex class.

You will create an apex class that resembles the response you obtain from the external system. There is a tool to help you create a class based on JSON responses.

Let's say your class looks like below

public class Response{
    @AuraEnabled public String lastName {get;set;}
    @AuraEnabled public String status{get;set;}
    @AuraEnabled public String address{get;set;}
    @AuraEnabled public String fullPhoneNumber {get;set;}
}

Then deserialize the response as below

List<Response> res = (List<Response>) JSON.deserialize(res.getBody(), List<Response>.class);

And make sure your return type from the method matches the returned value

public static List<Response> retrievePhone(String parameter){ 
  ....
  ....
   List<Response> res = (List<Response>) JSON.deserialize(res.getBody(), List<Response>.class);
   return res;

}

The Javascript controller will stream using the wire adaptor like below

import retrievePhone from "@salesforce/apex/ApexClassName.retrievePhone";

@wire(retrievePhone)
results;

You can then use results in the front end as below

<template>
     <template for:each={results} for:item='userNumber'>
     <lightning-layout class="slds-border_bottom" key={userNumber.ID}>
          <lighting-layout-item flexibility="auto, no grow">
               <div class="custom-box">
               <lightning-radio-group name="radioGroup" options={options} value={value} type="radio"></lightning-radio-group>
               </div>
          </lighting-layout-item>
          <lighting-layout-item flexibility="auto" padding="around-small">
               <div class="custom-box">
                    <p>{userNumber.lastName}</p>
                    <p>{userNumber.address}</p>
                    <p>{userNumber.fullPhoneNumber}</p>
               </div>
          </lighting-layout-item>
     </lightning-layout>
     </template>
</template>

The above approach is good if you have a JSON response that has fixed keys, meaning the JSON keys from the response does not change. Most of the APIs fall under this category where they have fixed data types for the response.

In case you have a dynamic response where data types may differ, then consider just returning a Map like Map<String, Object> using the same above as highlighted above.

1
  • quick question on the tool, does it do getter and setter method? Jun 27 at 22:36
2

Instead of deserializing the JSON on apex class, pass the JSON to javascript controller and parse the json into javascript object.

Also javascript will process the json much faster than apex and you will have control on json/javscript object to play with on javascript.

import retrievePhone from "@salesforce/apex/ApexClassName.retrievePhone";

responseReceived;

@wire(retrievePhone)
wiredRetrievePhone({ error, data }){
    if(data){
        this.responseReceived = JSON.parse(data);

        //now the responseReceived is an javascript object, we can fetch the properties as below.           
        console.log(this.responseReceived[0].lastName); //this will give you the lastName of your first element.
    }else
        //do the error processing
}
3
  • 1
    This answer needs to also be noted! When dealing with JSON from an external source, parsing the json in the front end (when you don't need to do any processing in the backend on it first) can be very beneficial. Not to mention, you may run into naming conventions in external systems which are reserved words in Apex and cannot be used in a custom apex class for deserialization such as Number!
    – stackasaur
    Jun 28 at 13:13
  • @Ranjit what would an example like that look like? I didn't know this was a possibility. I also thought processing on an apex class was the fastest option. Jun 28 at 17:53
  • 1
    @TristanBerger i have added an example, please have a look. Jun 28 at 18:42

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.