-
Notifications
You must be signed in to change notification settings - Fork 16
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Problem integrating Altcha to Formik, event handling behaves wrongly #77
Comments
Just a small update, if it could help... I've tried to append the "statechange" event handler only on "load" event like this import { useField } from "formik";
import React, { useEffect, useRef } from "react";
import { getConfig } from "../../../utils/commonMethodsFrontend";
export default function Altcha() {
const [field, meta, helpers] = useField("altcha");
// const { value } = meta;
const { setValue } = helpers;
const widgetRef = useRef(null);
useEffect(() => {
console.log("entering useEffect");
const handleStateChange = (ev) => {
console.log(ev);
if (ev.detail) {
// state can be: unverified, verifying, verified, error
if (ev.detail.state === "verified") {
// payload contains base64 encoded data for the server
setValue(ev.detail.payload);
console.log("set payload");
} else {
setValue("");
console.log("set empty");
}
}
};
const current = widgetRef.current;
const handleLoad = () => {
console.log("Widget fully loaded");
current.addEventListener("statechange", handleStateChange);
};
if (current) {
console.log("added load event listener");
current.addEventListener("load", handleLoad);
}
return () => {
if (current) {
console.log("removing event listeners...");
current.removeEventListener("load", handleLoad);
current.removeEventListener("statechange", handleStateChange);
}
};
}, [setValue]);
return (
<div className="field-container">
<div className="info">Accept the captcha to continue*</div>
<altcha-widget
ref={widgetRef}
challengeurl={getConfig("netlify_functions_url") + "/altcha-challenge"}
/>
{meta.error && meta.touched ? (
<div className="error">
<span>{meta.error}</span>
</div>
) : null}
</div>
);
} but nothing changes, the widget launch events only when going back and forth between pages. |
Hi, I don't see any |
Hi @ovx , yeah that was because I (wrongly) imported it in the parent component(s), I added the line in my component but nothing changed. Then I read this post on stack overflow and made some tests. Correct me if I'm wrong, I believe the react example you published on site works by "pure luck", as it's not a real life case where you need to wait for 3MB of webpacked stuff before the widget starts to work... The code is this, I hope it will be helpful to integrate the event handling stuff into the example code you posted (for react at least, I haven't checked how the other examples work). I'll delete the staging environment as soon as you check and make some tries with console opened and tell me you've got everything :) import { useField } from "formik";
import React, { useEffect, useRef } from "react";
import { getConfig } from "../../../utils/commonMethodsFrontend";
if (global.window) {
// Need to import like this as this shouldn't be bundled by webpack and Gatsby SSR
import("altcha");
}
export default function Altcha() {
const [field, meta, helpers] = useField("altcha");
const { setValue } = helpers;
// Reference to the widget
const widgetRef = useRef(null);
useEffect(() => {
console.log("entering useEffect...");
console.log("document.readyState = " + document.readyState);
const handleStateChange = (ev) => {
console.log("handling state change...");
if (ev.detail) {
if (ev.detail.state === "verified") {
console.log("setting payload value...");
setValue(ev.detail.payload);
} else {
setValue("");
}
}
};
const addWidgetListener = () => {
// Ensure the widget is loaded and available, then add the event listener
if (widgetRef.current) {
widgetRef.current.addEventListener("statechange", handleStateChange);
}
};
// If the document is fully loaded, attach the listener immediately
if (document.readyState === "complete") {
console.log(
"document.readyState is complete, I can add the widget listener now"
);
addWidgetListener();
} else {
// Otherwise, wait for the document to load before attaching the listener
console.log(
"document.readyState isn't complete, adding the listener on window.load ..."
);
window.addEventListener("load", addWidgetListener);
}
// Cleanup function to remove the event listeners
return () => {
if (widgetRef.current) {
console.log("removing statechange event listener on widget");
widgetRef.current.removeEventListener("statechange", handleStateChange);
}
console.log("removing load listener on window");
window.removeEventListener("load", addWidgetListener);
};
}, [setValue]);
return (
<div className="field-container">
<div className="info">Accept the captcha to continue*</div>
<altcha-widget
ref={widgetRef}
challengeurl={`${getConfig("netlify_functions_url")}/altcha-challenge`}
></altcha-widget>
{meta.error && meta.touched && (
<div className="error">
<span>{meta.error}</span>
</div>
)}
</div>
);
} |
Hi there!
I'm having an issue that I'm struggling to solve, I've lost many hours and I'd need a hand understanding if there's something that I'm missing of the whole...
I'm under GatsbyJS, and using Formik to handle a contact form in React, and I created a custom Field for Altcha that I use for form validation.
Here the code of my field(including some test console.log), code developed from your React example available in online documentation:
For what I know, I only instance an object of such component when I'm loading the form page, so I'm not passing it through any function that modifies the instance. The only doubt I have is for that
const [field, meta, helpers] = useField("altcha");
that is giving me the possibility to set field value directly from within this component and not by passing from a parent component. The field value is saved on a virtual object of values that Formik keep for validation, so "altcha" is the name of the saved element to be checked in Formik.The control lifecycle works correctly both in frontend and backend, but there's a strange behaviour that I cannot explain, I also tried to switch from 0.4.3 to new 1.1.0 to see if the problem changed but it seems to be worse than before.
Somehow the first time the React DOM loads, the event handler doesn't work. If you press on Altcha verification checkbox, no console.log is launched. Instead, if you go back and enter contact page again and verify with Altcha, you can see in debug console the event handler worked correctly.
You can check the strange behaviour here.
Do you have any idea about the possible problem here?
Thank you
The text was updated successfully, but these errors were encountered: