function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Afzaal HassanAfzaal Hassan 

Parse JSON response in LWC component

Hello 
I recently integrated a telephony system into Salesforce. I created a LWC component where a user would inout some values and pass it onto the JS for some processing and then the JS would give a message along with a "processing id." I have everything working except for the last part. I need to create another field in the LWC component that would populate the "message" field and also populate the "processing id" field. These fields should only show when they are available(returned by JS). The JS gives a JSON response and it is in this format:
{
  "type": "message",
  "message": "Payment Approved with Order Number: &&Secure.OrderNum&& and Processing ID: &&Secure.ProcessID&&"
}
so the processing id is within in the JSON message object. Can you please let me know how I should modify the JS and LWC html to pass and display this?

HTML:
<template>
    <lightning-card title="Secure Payment System" icon-name="custom:custom17">
            <div class="slds-m-around_medium">
                <lightning-input type="number" name="paymentAmount" required label="Order Amount" value="12.34" placeholder="Enter the amount of the transaction" formatter="currency" step="0.01"></lightning-input>
                <lightning-input pattern="[0-9]{5}" name="invoiceNumber" label="Order Number" value="12345" placeholder="Enter the 5 digit invoice number"></lightning-input>
                <div>
                    Processing Number: {processingId}
                </div>
                <div>
                    Status: {message}
                </div>
                <br>
                <lightning-button label="Transfer to Secure Pay" variant="brand" title="Start with Events" onclick={startSecurePaymentWithEvents} class="slds-m-left_x-small"></lightning-button>
                <lightning-
            </div>
    </lightning-card>
</template>

JS:
/* eslint-disable no-console */
import { LightningElement, api, wire, track } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import { getRecord } from 'lightning/uiRecordApi';
// These are the Contact Fields that we get and send as cavs
const FIELDS = [
    'Case.Contact.FirstName',
    'Case.Contact.LastName'
];

const cavBridgeURL = "SecurePay.BridgeURL";
let callVariables;
let self;
export default class SecurePayment extends LightningElement {
    bridgeclient = new BridgeClient();
    
    @api objectApiName;     // Set by Lightning to the name of the object type
    @api recordId;          // Set by Lightning to the ID of the object
    @track message;         //track changes to message so it can be displayed in lwc 
    
    // This uses this page's recordID to retrieve the contact's first and last name
    @wire(getRecord, { recordId: '$recordId', fields: FIELDS }) case;
    get contactFirstName() {
        return this.case.contact.data.fields.FirstName.value;
    }
    get contactLastName() {
        return this.case.contact.data.fields.LastName.value;
    }
    get paymentAmount() {
        const inputs = this.template.querySelectorAll('lightning-input');
        for (let i = 0; i < inputs.length; i++) {
            if (inputs[i].name === 'paymentAmount') {
                return inputs[i].value;
            }
        }
        return undefined;
    }
    get invoiceNumber() {
        const inputs = this.template.querySelectorAll('lightning-input');
        for (let i = 0; i < inputs.length; i++) {
            if (inputs[i].name === 'invoiceNumber') {
                return inputs[i].value;
            }
        }
        return undefined;
    }
    // Our constructor wires in the secpay's callback for the result event
    constructor() {
        super();
        self = this;
        
        secpay.initialize(this._onSecurePaymentStarted);
    }
    _onOpenEvent(bridgeURL) {
        // OK, if we get our URL then we be rolling!
        // Lets see if we can send a message to ourselves...
        console.log(`WebSocket Opened, Session URL: ${bridgeURL}, initiate secure payment IVR connection`);
        // Add the Bridge Server's URL as a CAV.
        // The script will use this to send real time messages and any other desired information back to this client
        // by POSTing JSON formatted messages to this URL.  This URL uniquely identifies this client's session.
        callVariables.push({name: cavBridgeURL, value: bridgeURL});
        // Now start the secure payment
        secpay.startSecurePayment(callVariables);
    }
    _onDataEvent(jsonData) {
        let eventData = JSON.parse(jsonData);
        // Is this a message?
        if (eventData.type === "message") {
            // Yes, show the status
            let message = eventData.message;
            const evt = new ShowToastEvent({
                title: "Payment Status",
                message: message,
                variant: 'info'
            });
            dispatchEvent(evt);
        }
        // Is this a result?
        else if (eventData.type === 'result') {
            // Yes, show the result
            let success = eventData.success;
            let message = eventData.message; 
            const evt = new ShowToastEvent({
                title: "Payment Result",
                message: message,
                variant: success ? 'success' : "error",
                url: "www.telephony.com"
            });
            dispatchEvent(evt);
        }
    }
    _onCloseEvent(error) {
        if (error) {
            const evt = new ShowToastEvent({
                title: "Bridge Event Connection Closed Due to Error",
                message: error.message,
                variant: "error"
            });
            dispatchEvent(evt);
        }
        console.log("WebSocket closed");
    }
    // Method used to initiate the secure payment
    _initiateSecurePayment(withEvents) {
        // eslint-disable-next-line no-debugger
        debugger;
        // Make sure our data is OK
        if (!this.paymentAmount || !this.invoiceNumber) {
            const evt = new ShowToastEvent({
                title: "Secure Payment",
                message: 'Amount and Invoice fields must both be set',
                variant: 'warning'
            });
            dispatchEvent(evt);
            return;
        }
        //*** Set the CAVs here ***
        callVariables = [
            {name: 'Secure.OrderNum', value: this.invoiceNumber},   // This comes from the LWC form
            {name: 'Secure.PayAmount', value: this.paymentAmount}    // This comes from the LWC form
        ];
        /
        if (withEvents) {
            // We don't know when to close our socket IF we made a sec payment request as we don't get an event when it completes.
            
            if (this.bridgeclient.isOpen()) {
                this.bridgeclient.close();
                return;
            }
            // Now kick things off by opening the bridge client.  The callbacks will drive us forward and once the socket is open and connected
            // we'll go ahead and start the secure payment call process.
            try {
                // Parms: wsURL, dataEvent, urlEvent, closeEvent
                // this.bridgeclient.open(this._onDataEvent, this._onOpenEvent, this._onCloseEvent, "ws://localhost:8888/bridge");
                this.bridgeclient.open(this._onDataEvent, this._onOpenEvent, this._onCloseEvent);
            } catch (ex) {
                const evt = new ShowToastEvent({
                    title: "Secure Payment",
                    message: `Failed trying to open connection to event Server: ${ex.message}`,
                    variant: 'error'
                });
                dispatchEvent(evt);
            }
        } else {
            secpay.startSecurePayment(callVariables);
        }
    }
    _onSecurePaymentStarted(message, error) {
        // Did we get an error?
        if (error) {
            // If we failed to start the sec pay conference then we need to close the 
            // Bridge Web Socket if we have a session open
            if (self.bridgeclient.isOpen()) {
                self.bridgeclient.close();
            }
        }
        const evt = new ShowToastEvent({
            title: (error ? "Failure" : "Success"),
            message: message,
            variant: (error ? 'error' : 'success'),
        });
        dispatchEvent(evt);
    }
    // Method used to initiate the secure payment
    startSecurePayment() {
        this._initiateSecurePayment(false);
    }
    // Method used to initiate the secure payment with events
    startSecurePaymentWithEvents() {
        this._initiateSecurePayment(true);
    }
   
}

I think I have not added properly (and dont know how to) take the processid variable that is embedded within the message type in the JSON. Any help, sample code would be great. Thanks
Khan AnasKhan Anas (Salesforce Developers) 
Hi Afzaal,

Greetings to you!

Please refer to the below links which might help you further with the above issue.

https://salesforce.stackexchange.com/questions/262010/access-value-of-json-in-js-controller

https://salesforce.stackexchange.com/questions/262003/how-to-access-data-returned-from-apex-class-in-js-controller-using-lightning-web

https://www.salesforcecodecrack.com/2019/08/make-rest-api-callout-in-lwc.html

I hope it helps you.

Kindly let me know if it helps you and close your query by marking it as solved so that it can help others in the future. It will help to keep this community clean.

Thanks and Regards,
Khan Anas