Validation Hooks
Validation Hooks allow you to validate user uploads during the interactive import process, so that your users can address any invalid data before it's imported into your app. When configuring your importer in the UseCSV admin, you can choose which columns to enable Validation Hooks for.
To use Validation Hooks you'll need to implement two callbacks: onRecordsInitial
and onRecordEdit
. They will pass you the uploaded data (for the columns Validation Hooks is enabled for) and allow you to return errors, info messages or heal values to the user.
Check using Validation Hooks codesandbox example
Check examples of using Data Healing:
- How to merge 2 or more columns codesandbox example
- How to split a column into 2 or more columns codesandbox example
- How to generate a unique id for a column codesandbox example
onRecordsInitial: Function
onRecordsInitial
callback function is triggered after the user uploads a file and once the column matching is completed. Data from the columns with Validation Hook
enabled will be sent to your frontend, so you can run your own validation and replace current value (Data Healing) or return rows with errors if any and custom error and info messages to be shown to the user. Data will be sent in batches of 1,000 rows by default if batchSize is not used. Please check our codesandbox example
onRecordsInitial
callback function parameters
type ParamsType = {
uploadId: string;
fileName: string;
importerId: string;
batch: {
index: number;
count: number;
totalRows: number;
};
user?: Record<string, string | number> | null;
metadata?: Record<string, string | number> | null;
rows: Array<{
row: number;
data: {
[columnName: string]: {
value: string | number | null;
isValid: boolean;
};
};
}>;
};
// onRecordsInitial parameters example
{
uploadId: 334,
fileName: "data.csv",
importerId: "123-456-789"
batch: {
index: 1;
count: 1;
totalRows: 3;
},
user: {
userId: "12345",
},
metadata: {
anotherId: "1",
},
rows: [{
row: 1,
data: {
email: {
value: "mari@gmail.com",
isValid: true
}
age: {
value: 5,
isValid: true
}
}
},
{
row: 2,
data: {
email: {
value: "john@gmail.com",
isValid: true
},
age: {
value: "not a number",
isValid: false
}
}
} {
row: 3,
data: {
email: {
value: "invalid@gmail@.com",
isValid: false
},
age: {
value: 35,
isValid: true
}
}
}
]
}
uploadId
: upload ID.fileName
: uploaded file name.importerId
: importer key that can be found in the admin panel.batch
: json object of batch details, with keys of:index
: number of batch starting from 1.count
: number of total batches expected to be received.totalRows
: number of total rows per file.
user
json object of user object if provided.metadata
json object of metadata object if provided.rows
: array of json objects of rows, with keys of:row
: number of row in the uploaded file starting from 1.data
: json object of columns:columnName
: array of json objects of the configured columns, with keys of:value
: value of cell.isValid
: boolean validation result according to the validation format configured for each column in admin panel when the column was created.
Return errors, info messages or heal values
onRecordsInitial hook accepts a returned value of an array of objects.
type ResponseType = Array<{
row: number;
data: {
[columnName: string]: Array<{
message: string;
level: "error" | "info" | "healing";
newValue?: string; // required for healing level
}>;
};
}>;
// Example of returned errors
return [
{
row: 1,
data: {
email: [
{
message: "Email already exists", // first error message
level: "error",
},
{
message: "Invalid email", // second error message (optional)
level: "error",
},
],
age: [
{
message: "Age must be 18 or above",
level: "info",
},
],
},
},
{
row: 2,
data: {
age: [
{
message: "Age must be a number",
level: "error",
},
],
},
},
{
row: 3,
data: {
email: [
{
message: "Typo has been corrected",
level: "healing",
newValue: "invalid@gmail.com", // (notice the original email was invalid@gmail@.com)
},
],
},
},
];
row
: required row number already included in the recieved data.data
: json object of columns:columnName
: array of json objects with keys of:message
andlevel
. At lease one column should be included in the response.message
: custom error message shown to user.level
:error
|info
:error
is used to define error messages.info
is used to define info messages.healing
is used to overwrite user's data.
newValue
: required string for healing level to replace current value in a cell.
onRecordEdit: Function
onRecordEdit
callback function is triggered after any of the cells is edited in the Match Columns step. The edited row will be sent to your frontend, so you can run your own validation and replace current value (Data Healing) or return errors if any and custom error and info messages to be shown to the user.
onRecordEdit
callback function parameters
type ParamsType = {
uploadId: string;
fileName: string;
importerId: string;
user?: Record<string, string | number> | null;
metadata?: Record<string, string | number> | null;
row: {
row: number;
data: {
[columnName: string]: {
value: string | number | null;
isValid: boolean;
};
};
};
};
// onRecordEdit parameters example
{
uploadId: 334,
fileName: "data.csv",
importerId: "123-456-789"
user: {
userId: "12345",
},
metadata: {
anotherId: "1",
},
row: {
row: 2,
data: {
email: {
value: "invalid@gmail@.com",
isValid: false
},
age: {
value: 35,
isValid: true
}
}
}
}
uploadId
: upload ID.fileName
: uploaded file name.importerId
: importer key that can be found in the admin panel.user
json object of user object if provided.metadata
json object of metadata object if provided.row
: json object of edited row, with keys of:row
: number of row in the uploaded file.data
: json object of columns:columnName
: array of json objects of the configured columns, with keys of:value
: value of cell.isValid
: boolean validation result according to the validation format configured for each column in admin panel when the column was created.
Return errors, info messages or heal values
onRecordEdit hook accepts a returned value of a JSON object or an array of objects.
// JSON object or array of objects
type ResponseType =
| {
row: number;
data: {
[columnName: string]: Array<{
message: string;
level: "error" | "info" | "healing";
newValue?: string | number | null;
}>;
};
}
| Array<{
row: number;
data: {
[columnName: string]: Array<{
message: string;
level: "error" | "info" | "healing";
newValue?: string | number | null;
}>;
};
}>;
// Example of returned errors
return Promise.resolve({
row: 2,
data: {
email: [
{
message: "Invalid email", // first error message
level: "error",
},
{
message: "Email does not exist", // second error message (optional)
level: "error",
},
{
message: "invalid@email.com", // optional suggestion (notice the original email was invalid@gmail@.com)
level: "info",
},
],
},
});
row
: required row number already included in the recieved data.data
: json object of columns:columnName
: json object with keys of:message
andlevel
. At lease one column should be included in the response.message
: custom error message shown to user.level
:error
|info
:error
is used to define error messages.info
is used to define info messages.healing
is used to overwrite user's data.
newValue
: required string for healing level to replace current value in a cell.