console.log errors only when they aren't visible #995
Replies: 1 comment 1 reply
-
Hi @simplecommerce. There's no such a feature, so let's do it without actually changing the package. The idea would be that we have to know three things:
Step 1. is easy - we walk the schema using [1] There's a problem with arrays, as the schema does not know how many elements will be there. It could be added as well by extending the available fields dynamically. Here's the code.import React, { useMemo, useState } from "react";
import SimpleSchema from "simpl-schema";
import { Bridge, joinName } from "uniforms";
import { SimpleSchema2Bridge } from "uniforms-bridge-simple-schema-2";
import { AutoFields, AutoForm, SubmitField } from "uniforms-unstyled";
const schema = new SimpleSchema({
x: { type: String, min: 1 },
y: Object,
"y.a": { type: String, min: 1 },
"y.b": { type: String, min: 1 },
z: { type: String, minCount: 1 },
"z.$": Object,
"z.$.a": { type: String, min: 1 },
"z.$.b": { type: String, min: 1 }
});
function useDebug(makeBridge: () => Bridge, dependencies?: unknown[]) {
const [fieldsErrored, setFieldsErrored] = useState([]);
const [fieldsRendered, setFieldsRendered] = useState([]);
const { bridge, fieldsAvailable, onValidate } = useMemo(() => {
const bridge = makeBridge();
const getField = bridge.getField.bind(bridge);
bridge.getField = (name) => {
if (joinName(null, name).slice(-1)[0] !== "$") {
setFieldsRendered((fields) =>
fields.includes(name) ? fields : fields.concat(name).sort()
);
}
return getField(name);
};
// Remember about .slice() as getSubfields is memoized.
const fieldsAvailable = bridge.getSubfields().slice().sort();
function gatherFieldsAvailable(field: string) {
const subfields = bridge.getSubfields(field).slice();
if (!subfields.includes("$")) {
try {
bridge.getField(joinName(field, "$"));
subfields.push("$");
} catch (error) {
// It's fine.
}
}
subfields.forEach((subfield) => {
subfield = joinName(field, subfield);
if (!fieldsAvailable.includes(subfield)) {
fieldsAvailable.push(subfield);
gatherFieldsAvailable(subfield);
}
});
}
fieldsAvailable.forEach(gatherFieldsAvailable);
fieldsAvailable.sort();
function onValidate(model: unknown, error: unknown) {
setFieldsErrored(
fieldsAvailable.filter(
(field) => !!bridge.getErrorMessage(field, error)
)
);
return error;
}
return { bridge, fieldsAvailable, onValidate };
}, dependencies);
return {
bridge,
fieldsAvailable,
fieldsErrored,
fieldsRendered,
onValidate
};
}
export function App() {
const {
bridge,
fieldsAvailable,
fieldsErrored,
fieldsRendered,
onValidate
} = useDebug(() => new SimpleSchema2Bridge(schema), []);
return (
<>
<pre>
<code>
{"fieldsAvailable = " + fieldsAvailable.join(", ")}
<br />
{"fieldsErrored = " + fieldsErrored.join(", ")}
<br />
{"fieldsRendered = " + fieldsRendered.join(", ")}
<br />
{"fieldsErrored \\ fieldsRendered = " +
fieldsErrored
.filter((field) => !fieldsRendered.includes(field))
.join(", ")}
</code>
</pre>
<AutoForm
placeholder
onValidate={onValidate}
schema={bridge}
onSubmit={(model) => alert(JSON.stringify(model, null, 2))}
>
<AutoFields fields={["x"]} />
<SubmitField />
</AutoForm>
</>
);
} We also briefly discussed it internally, and maybe we'll add it as a feature in the future. @wadamek65: you had some idea - could you share it here? |
Beta Was this translation helpful? Give feedback.
-
Hi,
I was wondering if there was any way to
console.log
errors for fields that aren't displayed or rendered in a form?For example, if I have a form that requires and
id
and aname
, and thename
field is a text field but theid
is passed to the model internally, if theid
field is empty for whatever reason, I would like to be able toconsole.log
and indicate that the field is missing since its not rendered on screen.This is just a simple scenario, but I would like to make it generic, since right now if a field isn't rendered, errors are caught and not throw/shown so sometimes it makes it difficult to debug.
Any ideas is appreciated, thanks!
Beta Was this translation helpful? Give feedback.
All reactions