Miotx
December 19, 2023, 10:53pm
1
Hello,
I am having an issue passing data into my custom component.
My model is as follows:
{
"link": {{link_token.value}}
}
and my iFrame code is:
<html>
<!--=================================================
STYLES AND PAGE INSTRUCTIONS. IGNORE THIS STUFF
=================================================-->
<head>
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@700&display=swap" rel="stylesheet">
</head>
<body style="background-color:#B1EEFC;">
<div class="outer">
<button id="link-button" style="background-color: white;border: #0A85EA;color: black;padding: 12px 32px;text-align: center;text-decoration: none;display: inline-block;font-size: 16px;margin: 4px 2px;box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19)">Link Account</button>
</div>
<!--=================================================
PLAID SCRIPTS. HERE'S THE STUFF YOU'LL EDIT!
=================================================-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>
<script type="text/javascript">
(function($) {
var handler = Plaid.create({
token: '{model.link}',
onSuccess: function(public_token, metadata) {
console.log('public token is:', public_token);
},
onExit: function(err, metadata) {
console.log('onexit invoked');
},
onEvent: function(eventName, metadata) {
console.log('event name is:', eventName);
}
});
$('#link-button').on('click', function(e) { handler.open() });
})(jQuery);
</script>
</body>
</html>
But for some reason the value of the model is not showing up when I enter {model.link} in my iFrame. What am I doing wrong?
Thanks!
Looks like you are missing the retool required portion in your iframe
<script
src="https://unpkg.com/react@18/umd/react.development.js"
crossorigin
></script>
<script
src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"
crossorigin
></script>
<div id="react"></div>
<script type="text/babel">
const MyCustomComponent = ({ triggerQuery, model, modelUpdate }) => (
<p>Hello, {model.name}!</p>
);
const ConnectedComponent = Retool.connectReactComponent(MyCustomComponent);
const container = document.getElementById("react");
const root = ReactDOM.createRoot(container);
root.render(<ConnectedComponent />);
</script>
EDIT: I pasted the wrong portion, correct should be displayed now.
Develop custom components | Retool Docs
1 Like
Miotx
December 19, 2023, 11:19pm
3
Wow! Thanks for the quick reply my friend! I added that portion to my iFrame before my script and sure enough, it did add the "model.link" to the text "Hello..." but how do I then insert that same value into my iFrame code "model.link"?
Thank you again!
Sorry I should have been clearer, wrap your code with the code that I pasted. So, the part I pasted that is below.
"
Hello, {model.name}!
"
is where you will paste your code then it should work.
I cant figure out how to escape it formatting in this forum. I'll circle it and paste it in a moment.
<script
src="https://unpkg.com/react@18/umd/react.development.js"
crossorigin
></script>
<script
src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"
crossorigin
></script>
<div id="react"></div>
<script type="text/babel">
const MyCustomComponent = ({ triggerQuery, model, modelUpdate }) => (
<html>
<!--=================================================
STYLES AND PAGE INSTRUCTIONS. IGNORE THIS STUFF
=================================================-->
<head>
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet'>
<link href="https://fonts.googleapis.com/css2?family=Roboto:wght@700&display=swap" rel="stylesheet">
</head>
<body style="background-color:#B1EEFC;">
<div class="outer">
<button id="link-button" style="background-color: white;border: #0A85EA;color: black;padding: 12px 32px;text-align: center;text-decoration: none;display: inline-block;font-size: 16px;margin: 4px 2px;box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19)">Link Account</button>
</div>
<!--=================================================
PLAID SCRIPTS. HERE'S THE STUFF YOU'LL EDIT!
=================================================-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>
<script type="text/javascript">
(function($) {
var handler = Plaid.create({
token: '{model.link}',
onSuccess: function(public_token, metadata) {
console.log('public token is:', public_token);
},
onExit: function(err, metadata) {
console.log('onexit invoked');
},
onEvent: function(eventName, metadata) {
console.log('event name is:', eventName);
}
});
$('#link-button').on('click', function(e) { handler.open() });
})(jQuery);
</script>
</body>
</html>
);
const ConnectedComponent = Retool.connectReactComponent(MyCustomComponent);
const container = document.getElementById("react");
const root = ReactDOM.createRoot(container);
root.render(<ConnectedComponent />);
</script>
Remove your comments if it still doesn't work, if I'm remember correctly I had to comment
/* like this */ instead of standard html comments
1 Like
Miotx
December 20, 2023, 12:33am
5
Thanks again. I tried that but it didn't work. I noticed the bottom of the code you pasted might be in the wrong place maybe? i.e. " ); const ConnectedComponent... "
Sorry to keep bugging but I really do appreciate you!
Thanks!
No worries,
This is code directly from a componant I have that is generating a SVG, its working.
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.8.0/html2pdf.bundle.min.js" crossorigin></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js" crossorigin></script>
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<div id="react12"></div>
<script type="text/babel">
const SVGComponent = ({ model }) => (
PUT YOUR CODE HERE
);
const ConnectedSVGComponent = Retool.connectReactComponent(SVGComponent);
const container = document.getElementById("react12");
const root = ReactDOM.createRoot(container);
root.render(<ConnectedSVGComponent />);
</script>
</div>
</body>
</html>
I'm unsure of the function of your code and what its supposed to be displaying, I do see the issue on my end as well though. Attempting to fix it.
Ok, this is failing to load the library it seems like, but I can see your link button for a millisecond during reload. Figure out what's going on with the Plaid library and fix the token key I just threw some numbers into and see what happens.
<!DOCTYPE html>
<html>
<head>
<title>React and Plaid</title>
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" crossorigin></script>
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js" crossorigin></script>
</head>
<body style="background-color:#B1EEFC;">
<div id="react1"></div>
<div class="outer">
<button id="link-button" style="background-color: white;border: #0A85EA;color: black;padding: 12px 32px;text-align: center;text-decoration: none;display: inline-block;font-size: 16px;margin: 4px 2px;box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19)">Link Account</button>
</div>
<script type="text/javascript">
// Plaid initialization code
(function($) {
var handler = Plaid.create({
token: '88888',
onSuccess: function(public_token, metadata) {
console.log('public token is:', public_token);
},
onExit: function(err, metadata) {
console.log('onexit invoked');
},
onEvent: function(eventName, metadata) {
console.log('event name is:', eventName);
}
});
// Event binding using jQuery (consider using React event handling instead)
$('#link-button').on('click', function(e) {
handler.open();
});
})(jQuery);
</script>
<script type="text/babel">
// React component definition
const SVGComponent = () => {
return (
<div>
</div>
);
};
// Render the React component to the container
const container = document.getElementById("react1");
const root = ReactDOM.createRoot(container);
root.render(<SVGComponent />);
</script>
</body>
</html>
1 Like
Miotx
December 20, 2023, 2:57am
9
Interesting why its doing that. Below is a sandbox token that we can use to test. It's from a test staging environement but that is basically what I have in my model and what I want to pass onto the iFrame.
link-sandbox-ee944336-f7e1-4156-9d71-3a9d7b8be6c6
Thank you again!
I'm unable to test for you right now, but I'm fairly sure this is a problem w mixing jQuery and React. There's 2 common proplems that can pop up, how both languages manipulate the DOM and how events are handled. With jQuery, u usually directly edit a node by selecting then modifying. With frameworks like React they, for the most part, generate the DOM from data then regenerate parts when values change and in Reacts case, it can optimize this by reusing DOM nodes. The biggest problem is that jQuery and React don't know about each other, so if one generates a new DOM and the other is expecting something to be there, its a problem.
TLDR; For your problem and considering how @stevenhdsdoor said he saw the correct value for a split second on refresh, jQuery is attaching the .on() event to the button, then React is regenerating the DOM including the button which now no longer has the .on() event attached to it.
<!DOCTYPE html>
<html>
<head>
<title>React and Plaid</title>
<script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" crossorigin></script>
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js" crossorigin></script>
</head>
<body style="background-color:#B1EEFC;">
<div id="react1"></div>
<div class="outer">
<!-- we want to render the button here -->
</div>
<script type="text/babel">
// React component definition
const SVGComponent = () => {
const handler = () =>{
Plaid.create({
token: '88888',
onSuccess: function(public_token, metadata) {
console.log('public token is:', public_token);
},
onExit: function(err, metadata) {
console.log('onexit invoked');
},
onEvent: function(eventName, metadata) {
console.log('event name is:', eventName);
}
});
}
const btn_style = {
background-color: "white"
}
return (
<div>
<button id="link-button" style={btn_style} onClick={handler} >Link Account</button>
</div>
);
};
// Render the React component to the container
const container = document.getElementById("outer");
const root = ReactDOM.createRoot(container);
root.render(<SVGComponent />);
</script>
</body>
</html>
I haven't slept in a couple days, so I appologize for mixing languages/syntax and any other ridiculous errors I managed to make (I'ma be happy if there's no logic errors honestly). You probably could leave the function the way you had it, but Steven already gave the code for the component so might as well use it?
Miotx
December 20, 2023, 6:13pm
11
Hello again my friend,
Were you able to use the sandbox token to get it working on your end?
Thanks,
Miotx
December 21, 2023, 7:35pm
12
Hi Steven,
I had to create a new sandbox link token as that one expired:
link-sandbox-d8741658-5a14-42ec-9ab7-3730b4645813
Let me know if you have a chance to take a look at it
Thanks!
Miotx
December 25, 2023, 7:00am
13
I was able to get it done this way and it worked:
My model is like this:
{
"link": "{{link_token.value}}"
}
And my iFrame is like this:
<html>
<!--=================================================
STYLES AND PAGE INSTRUCTIONS. IGNORE THIS STUFF
=================================================-->
<head>
<link href='https://fonts.googleapis.com/css?family=Poppins' rel='stylesheet'>
<link href="https://fonts.googleapis.com/css2?family=Poppins:wght@700&display=swap" rel="stylesheet">
</head>
<body style="background-color:#B1EEFC;">
<div class="outer">
<button id="link-button" style="background-color: white;border: #0A85EA;color: black;padding: 12px 32px;text-align: center;text-decoration: none;display: inline-block;font-size: 14px;margin: 4px 2px;box-shadow: 0 8px 16px 0 rgba(0,0,0,0.2), 0 6px 20px 0 rgba(0,0,0,0.19)">+ Add New Bank or Credit Card Account</button>
</div>
<script
src="https://unpkg.com/react@18/umd/react.development.js"
crossorigin
></script>
<script
src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"
crossorigin
></script>
<!--================================================
PLAID SCRIPTS. HERE'S THE STUFF YOU'LL EDIT!
=================================================-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
<script src="https://cdn.plaid.com/link/v2/stable/link-initialize.js"></script>
<script type="text/javascript">
window.Retool.subscribe(function (model) {
var handler = Plaid.create({
token: model.link,
onSuccess: function(public_token, metadata) {
console.log('public token is:', public_token);
},
onExit: function(err, metadata) {
console.log('onexit invoked');
},
onEvent: function(eventName, metadata) {
console.log('event name is:', eventName);
}
});
$('#link-button').on('click', function(e) { handler.open() });
})(jQuery);
</script>
</body>
</html>
Thanks for all the help. Hope this helps someone that was a little stuck like me!
Thanks!
1 Like