0

Here is my initial apex that currently functions and will return json.

public class samCall {
@AuraEnabled

public static String samQuery(string accountDuns) {

            HttpRequest req = new HttpRequest();
            req.setEndpoint( 'callout:samAPI/entity-information/v2/entities?ueiDUNS=' + accountDuns);
            req.setHeader( 'X-Api-Key', '{!$Credential.Password}' );
            req.setMethod('GET');
            Http http = new Http();
            HTTPResponse res = http.send(req);

            return res.getBody();
        }
}

Here is Js -

import { LightningElement,wire,track,api } from 'lwc';

import getDuns from '@salesforce/apex/samCall.samQuery';

export default class searchSam extends LightningElement {

@api dunsNumber;
@track samRecord;
@track error;
@track data;

    handleClick(event){

        let inputDuns = this.template.querySelector('lightning-input').value;

        this.dunsNumber = inputDuns;

    }

    @wire(getDuns,{ accountDuns: '$dunsNumber'})

    samData({ error, data }) {

        if (data) {

            //console.log('RecordId is'+recordId);
            this.samRecord = data;
            console.log(samRecord);

            this.error = undefined;

        } else if (error) {

            //console.log('Error block');
            this.error = error;

            this.samRecord = undefined;

        }

    }

 }

---->> Final Apex

public class samCall {

@AuraEnabled(cacheable=true)
public static string samQuery(string accountDuns) {

    HttpRequest req = new HttpRequest();
    req.setEndpoint( 'callout:samAPI/entity-information/v2/entities?ueiDUNS=' + accountDuns);
    req.setHeader( 'X-Api-Key', '{!$Credential.Password}' );
    req.setMethod('GET');
    Http http = new Http();
    HTTPResponse res = http.send(req);

    entityApi parsedResponse =  (entityApi) JSON.deserialize(res.getBody(), entityApi.class);

    Object entReg = parsedResponse.entityData[0].entityRegistration;

    String pretty = JSON.serialize(entReg);

    System.debug('Is this pretty? >>>' + ' ' + pretty);

    return pretty;

}


public class entityApi {

    public Integer totalRecords;
    public List<EntityData> entityData;
    public List<NaicsList> naicsList;
}

    public class FinancialInformation {
        public String creditCardUsage;
        public String debtSubjectToOffset;
    }

    public class NaicsList {
        public String naicsCode;
        public String naicsDescription;
        public String sbaSmallBusiness;
    }

    public class EntityData {
        public EntityRegistration entityRegistration;
        public CoreData coreData;
        public Assertions assertions;
        public PointsOfContact pointsOfContact;
    }

    public class PhysicalAddress {
        public String addressLine1;
        public String city;
        public String stateOrProvinceCode;
        public String zipCode;
        public String zipCodePlus4;
        public String countryCode;
    }

    public class Assertions {
        public GoodsAndServices goodsAndServices;
        public DisasterReliefData disasterReliefData;
        public EdiInformation ediInformation;
    }

    public class GovernmentBusinessAlternatePOC {
        public String firstName;
        public String middleInitial;
        public String lastName;
        public String title;
        public String addressLine1;
        public String addressLine2;
        public String city;
        public String stateOrProvinceCode;
        public String zipCode;
        public String zipCodePlus4;
        public String countryCode;
    }

    public class EdiInformation {
        public String ediInformationFlag;
    }

    public class DisasterReliefData {
        public String disasterRegistryFlag;
        public String bondingFlag;
        public List<GeographicalAreaServed> geographicalAreaServed;
    }

    public class CoreData {
        public EntityInformation entityInformation;
        public PhysicalAddress physicalAddress;
        public PhysicalAddress mailingAddress;
        public String congressionalDistrict;
        public GeneralInformation generalInformation;
        public FinancialInformation financialInformation;
    }

    public class PointsOfContact {
        public GovernmentBusinessPOC governmentBusinessPOC;
        public GovernmentBusinessPOC electronicBusinessPOC;
        public GovernmentBusinessAlternatePOC governmentBusinessAlternatePOC;
        public GovernmentBusinessAlternatePOC electronicBusinessAlternatePOC;
        public GovernmentBusinessAlternatePOC pastPerformancePOC;
        public GovernmentBusinessAlternatePOC pastPerformanceAlternatePOC;
    }

    public class GeneralInformation {
        public String entityStructureCode;
        public String entityStructureDesc;
        public String entityTypeCode;
        public String entityTypeDesc;
        public String profitStructureCode;
        public String profitStructureDesc;
        public String organizationStructureCode;
        public String stateOfIncorporationCode;
        public String stateOfIncorporationDesc;
        public String countryOfIncorporationCode;
        public String countryOfIncorporationDesc;
    }

    public class GoodsAndServices {
        public String primaryNaics;
        public List<NaicsList> naicsList;
        public List<PscList> pscList;
    }

    public class GovernmentBusinessPOC {
        public String firstName;
        public String middleInitial;
        public String lastName;
        public String title;
        public String addressLine1;
        public String addressLine2;
        public String city;
        public String stateOrProvinceCode;
        public String zipCode;
        public String zipCodePlus4;
        public String countryCode;
    }

    public class EntityInformation {
        public String entityURL;
        public String entityDivisionName;
        public String entityDivisionNumber;
        public String entityStartDate;
        public String fiscalYearEndCloseDate;
        public String submissionDate;
    }

    public class PscList {
        public String pscCode;
        public String pscDescription;
    }

    public class Links {
        public String selfLink;
    }

    public class GeographicalAreaServed {
        public String geographicalAreaServedStateCode;
        public String geographicalAreaServedStateName;
        public String geographicalAreaServedCountyCode;
        public String geographicalAreaServedCountyName;
        public String geographicalAreaServedmetropolitanStatisticalAreaCode;
        public String geographicalAreaServedmetropolitanStatisticalAreaName;
    }

    public class EntityRegistration {
        public String samRegistered;
        public String ueiSAM;
        public String ueiDUNS;
        public String entityEFTIndicator;
        public String cageCode;
        public String dodaac;
        public String legalBusinessName;
        public String dbaName;
        public String purposeOfRegistrationCode;
        public String purposeOfRegistrationDesc;
        public String registrationStatus;
        public String registrationDate;
        public String lastUpdateDate;
        public String registrationExpirationDate;
        public String activationDate;
        public String ueiStatus;
        public String ueiExpirationDate;
        public String ueiCreationDate;
        public String noPublicDisplayFlag;
        public String exclusionStatusFlag;
        public String exclusionURL;
        public String dnbOpenData;
    }
}

Final JS ----

import { LightningElement,wire,track,api } from 'lwc';

import getDuns from '@salesforce/apex/samCall.samQuery';

export default class searchSam extends LightningElement {

@api dunsNumber;
@track samRecord;
@track error;
@track data;

    handleClick(event){

        let inputDuns = this.template.querySelector('lightning-input').value;

        this.dunsNumber = inputDuns;

    }

    @wire(getDuns,{ accountDuns: '$dunsNumber'})
    
    samData({ error, data }) {

        if (data) {

            //console.log('RecordId is'+recordId);
            this.samRecord = JSON.parse(data);

            this.error = undefined;

        } else if (error) {

            //console.log('Error block');
            this.error = error;

            this.samRecord = undefined;

        }

    }

 }

Final Html ----

<template>
<lightning-card title="Check SAM.GOV" icon-name="custom:custom63">
        <lightning-input type="text" label="Enter DUNS" value={dunsNumber}> </lightning-input>
            <lightning-button label="Check" onclick={handleClick} class="slds-m-left_x-small"></lightning-button>
            
            <p>Displaying SAM Information</p>
            DUNS Input: {dunsNumber}


            <template if:true={samRecord}>
                <p>Legal Business Name: {samRecord.legalBusinessName} </p>
                <p>Cage Code: {samRecord.CageCode} </p>
                <p>SAM UEI: {samRecord.ueiSAM} </p>
                <p>SAM Expiration Date {samRecord.registrationExpirationDate} </p>
                <p>Purpose of Registration: {samRecord.purposeOfRegistrationDesc} </p>
                <p>Registration Status: {samRecord.registrationStatus} </p>
            </template>
            <template if:true={error}>
                <p>1. Whoops! {error} </p>
            </template>

        </lightning-card>
</template>
7
  • Unless your JSON includes reserved words there's no need to use JSON2Apex; You can create your own data objects, or even use JSON.deserializeUntyped to get a structured Map<String, Object>, where the objects are either primitive values (like string, integer or boolean), arrays or other Maps. See the documentation.
    – Phil W
    Jun 4 at 14:14
  • To clarify on this, I'm just going to add a new object: public static Object deserializeUntyped(String res.getBody()){ Map<String, Object> m = (Map<String, Object>) JSON.deserializeUntyped(jsonInput); } Or can I just add (below) in place of return res.getBody(); Map<String, Object> m = (Map<String, Object>) JSON.deserializeUntyped(jsonInput); Jun 4 at 14:25
  • That's not a class.
    – Phil W
    Jun 4 at 14:26
  • sorry meant object* Jun 4 at 14:29
  • I suspect you meant a new method or variable, though the first code sample you have posted in the comment is a mix of a method declaration and a method invocation and the second sample is what I suggest you use :) If you do, you can drop the JSON2Apex stuff entirely since it is unnecessary.
    – Phil W
    Jun 4 at 14:32
2

You can simply add JSON.deserializeUntyped as Phil pointed out, if you don't need any additional processing in Apex and just want to pass info to LWC.

public class samCall {

@AuraEnabled
public static Map<String, Object> samQuery(string accountDuns) {

            HttpRequest req = new HttpRequest();
            req.setEndpoint( 'callout:samAPI/entity-information/v2/entities?ueiDUNS=' + accountDuns);
            req.setHeader( 'X-Api-Key', '{!$Credential.Password}' );
            req.setMethod('GET');
            Http http = new Http();
            HTTPResponse res = http.send(req);

            return (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
        }
}

JSON2Apex is useful for easier work in Apex with responses from the server, in order to do so you can write your code like this.

public class samCall {

@AuraEnabled
public static Object samQuery(string accountDuns) {

            HttpRequest req = new HttpRequest();
            req.setEndpoint( 'callout:samAPI/entity-information/v2/entities?ueiDUNS=' + accountDuns);
            req.setHeader( 'X-Api-Key', '{!$Credential.Password}' );
            req.setMethod('GET');
            Http http = new Http();
            HTTPResponse res = http.send(req);

            // I'd recommend renaming JSON2Apex to something more meaningful for your context
            JSON2Apex parsedResponse =  (JSON2Apex) JSON.deserialize(res.getBody(), JSON2Apex.class);

             // do some processing with your response
             Object processedResult = '';
             return processedResult;

        }
        // Your JSON2Apex wrapper classes
}
13
  • I figured out the inner issue, that was simple. Testing now. Edit from testing, having issues with pulling specific data. Jun 4 at 14:59
  • then use the second version, if you want to do some processing in Apex. Or what exactly you're currently struggling with? If you question is answered, please accept my answer and close the question
    – ytiq
    Jun 4 at 15:10
  • I think I was having issues due to the AuraEnabled missing Cache true. I'm going to see if that's the case. Jun 4 at 17:47
  • am I supposed to be handling the return differently from JS with the Map<String, Object> Method? Jun 4 at 18:49
  • I still don't understand is your current issue in JS or in Apex?
    – ytiq
    Jun 4 at 19:49
2

Given your original code, you may as well just do the parsing client-side:

return res.getBody();

And:

samData({ error, data }) {
    if (data) {
        this.samRecord = JSON.parse(data);
3
  • This isn't working for me on the JS side. I believe because I've been working with a String output from Apex or the Map<String, Obj> Jun 4 at 18:48
  • @User_11223344 If you don't do any parsing on it, it should just work with JSON on the client-side. What errors are you getting when you try it that way?
    – sfdcfox
    Jun 4 at 22:59
  • I don't get an error, it doesn't display anything. Jun 7 at 17:16

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