2

I'm trying to create an integration with Plaid and they have the following script that runs to get variables from their service. I need to be able to capture these outputs and pass to my controller to continue the flow but am not very experience with Javascript Remoting or Javascript for that matter.

Here's the code I have, I need to get the public_token and metadata.account_id to my controller. I've tried filling fields on my VF page with those values but have had no luck getting that to work.

I don't have my controller set up in the example as I tried to take another approach.

Any help is appreciated!

    <apex:page standardController="Account">
        <button id='linkButton'>Open Plaid Link</button>
            <script src="https://cdn.plaid.com/link/stable/link-initialize.js"></script>
            <script type="text/javascript">
            var linkHandler = Plaid.create({
            env: 'tartan',
            clientName: 'Plaid Test',
            key: 'xxxxxKeyxxxxx',
            product: 'auth',
            selectAccount: true,
            onSuccess: function(public_token, metadata) {
            // Send the public_token and account ID to your app server.
            console.log('public_token: ' + public_token);
            console.log('account ID: ' + metadata.account_id);
                var ptoken = public_token;
                var acctId = metadata.account_id;
            document.getElementbyId('{!$Component.theForm.thepageblock.publicToken}').value = ptoken;
                return false;
            },
            });

            // Trigger the Link UI
            document.getElementById('linkButton').onclick = function() {
            linkHandler.open();
            };
        </script>

        <apex:form id="theForm">
            <apex:pageblock id="thepageblock">
                    <apex:inputText id="publicToken"/>
                    <br />
                    <apex:inputText id="accountId"/>
            </apex:pageblock>
        </apex:form>
</apex:page>
  • So you want to get apex:inputText id="publicToken" value in controller? and <apex:inputText id="accountId"/> – Ratan Paul Feb 12 '16 at 15:52
  • I was trying to write it to the visualforce page, thinking I could add it as a hidden input field and then pass that value to my controller so I could make another call using that variable. If there's away that I can pass those values directly from my Javascript method to my controller without having to use the hidden field, that would be ideal. – sfdcJameson Feb 12 '16 at 16:19
3

You have a few options here.

  1. An actionFunction:

actionFunctions are created with the visualforce tag and will create a JavaScript method that you can invoke from anywhere else on your page (an onclick, your own script, etc.)

Within the actionFunction, you can put an tag which will link a var you pass to the actionFunction to a property on your controller. Check this sample controller/page that demonstrates the general setup:

<apex:actionFunction action="{!controllerMethod}" name="javascriptFunctionName" reRender="stuff">
    <apex:param name="publicToken" value=""/>
    <apex:param name="accountId" value=""/>
</apex:actionFunction>

Now, in your JavaScript, you can do the following:

javascriptFunctionName(public_token, metadata.account_id);

Invoking that JS function will invoke the action in your actionFunction and assign the values you pass as args to the params. So then in your controller, you can do this:

public void controllerMethod() {
    String publicToken = ApexPages.currentPage().getParameters().get('publicToken');
    String accountId = ApexPages.currentPage().getParameters().get('accountId');
    //Do whatever you need to do here with the publicToken and accountId.
}
  1. A RemoteAction: https://developer.salesforce.com/docs/atlas.en-us.pages.meta/pages/pages_js_remoting_example.htm

RemoteActions expose methods in your apex controller extension to your scripts. In your controller, you would have a method that would look something like this:

@RemoteAction
public static void controllerMethod(String publicToken, String accountId) {
    //Do what you need to with publicToken and accountId...
}

The way you would use this in your JavaScript then is like this:

ControllerName.controllerMethod(public_token, metadata.account_id, function(result, event) {
    //This is a callback which will have the result if your controller method returns any value.
});

You can ALSO write the same method invocation like this:

Visualforce.remoting.Manager.invokeAction("ControllerName.controllerMethod", public_token, metadata.account_id, function(result, event) {
    //This is a callback which will have the result if your controller method returns any value.
});
  • 1
    Note that if you go the route of the RemoteAction that your controller method must be static, and must have that RemoteAction annotation. Consider that since your method must be static, you will be unable to explicitly name properties or other non-static methods in your controller. – Matt Thomas Feb 12 '16 at 17:06
1

here's what I ended up doing. Thanks a ton for the input @Matt.

I ended up just calling the method from within the Javascript and then passed the variables through that process. There are some redundancies in the code below that I was using to test things out but the key was to include the SOAP scripts and call the method from within the JS Try/Catch blocks.

<apex:page controller="RemoteController" showHeader="false" sidebar="false">
    <head>
            <script src="/soap/ajax/15.0/connection.js" type="text/javascript"></script>
            <script src="/soap/ajax/15.0/apex.js" type="text/javascript"></script>
            <script src="https://cdn.plaid.com/link/stable/link-initialize.js"></script>
            <script type="text/javascript">
            var linkHandler = Plaid.create({
            env: 'tartan',
            clientName: 'Plaid Test',
            key: 'xxxxxxxxxKeyxxxxxxxxxxx',
            product: 'auth',
            selectAccount: true,
            onSuccess: function(public_token, metadata) {
            // Send the public_token and account ID to your app server.
            console.log('public_token: ' + public_token);
            console.log('account ID: ' + metadata.account_id);
                try{
                sforce.connection.sessionId = '{!$Api.Session_ID}'; 
                sforce.apex.execute("RemoteController", "tokenExchange", {acctId : metadata.account_id, publicToken : public_token});
                }
                catch(e){
                    alert(e);
                }
            },
            });

            // Trigger the Link UI
            document.getElementById('linkButton').onclick = function() {
            linkHandler.open();
            };
        </script>

        <script>
        window.onload=function()
        {

         var msg = window.location.href.match(/\?rcid=(.*)/);
            document.getElementById("rcid").value = msg[1];
        };
    </script>
    </head>
    <body>
        <div>
            <button id='linkButton' onclick="linkHandler.open()">Open Plaid Link</button>
        </div>
        <div>
            <form>
                Token:<br />
                <input type="text" id="publicToken" name="publicToken" size="150" value="{!publicToken}"/><br />
                Acct Id: <br />
                <input type="text" id="acct_id" size="100" value="{!acctId}"/><br />
                SFDC RecordId: <br />
                <input type="text" id="rcid" />
            </form>
        </div>
    </body>
</apex:page>
  • I want to fetch the account & its related transactions using above script. How to do that using controller & its methods. Kindly help! – snehakem Mar 8 '16 at 10:26

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.