I have an application using the teller.io API. I have to import a script from them to initiate authentication within my react app, as they have no react library.
After adding the script to the DOM, I have to use a function from it. However, React won't recognize the function as it's only defined at runtime when the script is added.
The following is my solution, and it works, but I know this cannot be a good way to accomplish this so if anyone can recommend a proper solution that'd be amazing.
useEffect(() => {
const script = document.createElement("script");
script.src = "https://cdn.teller.io/connect/connect.js";
script.async = true;
document.head.appendChild(script);
var tellerConnect = window.TellerConnect.setup({
applicationId: "Your application ID e.g app_xxxxxx",
onInit: function() {
console.log("Teller Connect has initialized");
},
// Part 3. Handle a successful enrollment's accessToken
onSuccess: function(enrollment) {
console.log("User enrolled successfully", enrollment.accessToken);
},
onExit: function() {
console.log("User closed Teller Connect");
}
});
var el = document.getElementById("myButton");
el.addEventListener("click", function() {
// tellerConnect.open();
});
}, []);
Line 6, with the "window.TellerConnect.setup is what I'd like to fix/replace with a more proper solution.
Teller.io docs for this script/setup can be found at: Teller Connect
Thanks in advance!
A pattern (a hook and a pure-JS loader) like this might work for you.
This doesn't take into account multiple components attempting to use the API with e.g. different application IDs.
function loadScript(elementId, src) {
if (!document.getElementById(elementId)) {
const script = document.createElement('script');
script.src = src;
script.id = elementId;
document.head.appendChild(script);
}
}
/**
* Ensure the Teller Connect script is loaded.
*
* Returns the `window.TellerConnect` object once it exists.
*/
function loadTellerConnect() {
return new Promise((resolve) => {
function check() {
if (window.TellerConnect) {
return resolve(window.TellerConnect);
}
loadScript('teller-script', 'https://cdn.teller.io/connect/connect.js');
setTimeout(check, 100);
}
check();
});
}
/**
* Load and configure Teller Connect.
* @returns The Teller API (or null if it hasn't yet loaded).
*/
function useTellerAPI(setupArgs) {
const [tellerApi, setTellerApi] = React.useState(null);
React.useEffect(() => {
loadTellerConnect().then((tellerApi) => {
tellerApi.setup(setupArgs);
setTellerApi(tellerApi);
});
}, [setupArgs]);
return tellerApi;
}
function MyComponent() {
const tellerConnect = useTellerAPI({
applicationId: 'Your application ID e.g app_xxxxxx',
});
return (
<button onClick={() => tellerConnect?.open()} disabled={!tellerConnect}>
Open Teller
</button>
);
}