Accept data client-side
Flatfile sends validated data for you to accept after a user completes their import.
Data sent will have passed all validation rules and not include data dismissed during submission.
Processing data client-side with onData
This example shows how you might pass records to a front-end function to process.
const importData = Flatfile.requestDataFromUser({
token, // a jwt token for production
onData: async (chunk, next) => {
const records = chunk.records;
// an example function where chunked records are handled
await doSomeApiWork(records);
// process next chunk
next();
},
});
Notice onData
passes data to the function with chunk
and next
.
chunk
is a group of data records that is processed at a time. Data is passed in chunks to avoid exceeding the browser's memory limit when very large files are uploaded. The default number of records in each chunk is 1,000. This number can be adjusted using the chunkSize
option on Flatfile.requestDataFromUser
.
next()
is called to process the next chunk and to enable the default submit behavior.
See the following RecordsChunk
table that defines the chunk object.
Even if you do not plan to process data client-side, you should still include an onData
function that calls next()
to enable the default submit behavior.
RecordsChunk
When processing data, Flatfile allows you to manage how much data you want to process at once by configuring chunkSize
. Each chunk
inside onData
contains the following properties:
Property | Type | Description |
---|---|---|
recordIds | [number, ...] | List of Record IDs included in this chunk of records. |
records | [FlatfileRecord, ...] | An array of records |
totalChunks | number | The number of chunks to process in total. |
currentChunkIndex | number | The current index (starting at 0) of the chunk being processed. |
The following table describes the record object within the array of records.
An example console log for each part of the record object
onData: async (chunk, next) => {
chunk.records.forEach(function(record) {
// An object of record's cells e.g. `{ name: 'John', age: 22 }`
console.log(record.data)
// Unique identifier for the record provided by Flatfile
console.log(record.recordId)
// whether or not the record is valid
console.log(record.valid)
// Specifies the record's status.
console.log(record.status)
// array of all messages
console.log(record.allMessages)
// array of error level messages
console.log(record.errors)
// array of warning level messages.
console.log(record.warnings)
// array of info level messages
console.log(record.info)
}
// process next chunk
next();
}
FlatfileRecord
Property | Type | Description |
---|---|---|
data | { key: "value" } | An object of record's cells e.g. { name: 'John', age: 22 } |
recordId | number | Unique identifier for the record provided by Flatfile |
valid | boolean | Determines whether or not the record is valid based on the record type, uniqueness and additional validations. |
status | "review", "dismissed" or "accepted" | Specifies the record's status. |
allMessages | [RecordMessage, ...] | An array of messages |
errors | [RecordMessage, ...] | An array of messages with "error" level |
warnings | [RecordMessage, ...] | An array of messages with "warn" level |
info | [RecordMessage, ...] | An array of messages with "info" level |
An example console log for each RecordMessage
onData(chunk, next) {
chunk.records.forEach(function(record) {
if (record.valid && record.status === 'accepted') {
console.log(`${record.recordId} was accepted!`)
console.log('Here is the record', record.data)
}
record.allMessages.forEach(function(msg) {
if (msg.level === 'info') {
console.log(`${msg.field}: ${msg.message}`)
}
if (msg.level === 'warn') {
console.warn(`${msg.field}: ${msg.message}`)
}
if (msg.level === 'error') {
console.error(`${msg.field}: ${msg.message}`)
}
})
})
//processes next chunk
next();
}
RecordMessage
Property | Type | Description |
---|---|---|
level | "info", "warn" or "error" | Determines the level of the message per record. "error" messages will automatically set valid to false |
field | string | Field's key |
message | string | Text message |
Rejecting Records
If you find additional validation errors when accepting incoming data, you can use PartialRejection
to reject some records and have the user resolve them within the Flatfile importer. When configured, your importers will be cycled back into Review until all records are accepted or dismissed.
import { PartialRejection, RecordError } from "@flatfile/sdk";
Flatfile.requestDataFromUser({
onData: (chunk, next) => {
// Do something that causes a failure...
chunk.records.forEach(console.log);
next(
// A PartialRejection could be created with a list or a single RecordError.
new PartialRejection(
// A RecordError should be created with an record (or record id)
// and a list of validation errors.
new RecordError(1, [{ field: "full_name", message: "This person already exists." }]),
),
);
},
});
Handling errors client-side with onError
The default behavior for handling errors is a browser dialog displaying an error message. You can suppress the default behavior and define your own error handling using the onError
option, which receives an error
object with the error code, debug message, and user-facing message. You can then pass this information to your application and handle it however you like.
Example:
const importData = Flatfile.requestDataFromUser({
token, // a jwt token for production
onData: async (chunk, next) => {
await doSomeApiWork(chunk.records);
// process next chunk
next();
},
onComplete() {},
onError(error) {
// see below for possible errors that can be passed
console.log("code", error.code);
console.log("debug", error.debug);
console.log("userMessage", error.userMessage);
// perform custom error handling in your UI
},
});
UnauthorizedError
Property | Value |
---|---|
code | FF-UA-XX |
debug | The JWT was not signed with a recognized private key or you did not provide the necessary information to identify the end user |
userMessage | There was an issue establishing a secure import session. |
Error codes:
FF-UA-00
-token
is missing or is signed with invalid private key.FF-UA-01
- The embed ID was not provided as a value for theembed
property in JWT.FF-UA-02
- The embed ID provided as a value for theembed
property is invalid. Make sure it contains a valid UUID.FF-UA-03
- The embed does not exist.FF-UA-04
- The embed does not have an active private key. Please reset your private key using Flatfile Dashboard.FF-UA-05
- Your request was in developer mode, but used a known production embed ID. Please make sure you implement "Securing Data" part before using production embed.
RequestError
Property | Value |
---|---|
code | FF-RE-00 |
debug | Internal Server Error: "API error description" |
userMessage | A network request failed to complete. Please try again. |
Common causes:
- The user's internet connection is unstable or offline
- Flatfile is experiencing internal system issues (See https://status.flatfile.io)
ImplementationError
Property | Value |
---|---|
code | FF-IE-00 |
debug | embedId , token or onAuth property is required to initialize Flatfile. |
userMessage | There was a configuration error preventing the data importer from loading. |
Common causes:
embedId
,token
oronAuth
property is missing in the config.
ChunkTimeoutExpiredError
Property | Value |
---|---|
code | FF-CT-01 |
debug | Something went wrong while submitting your data. |
userMessage | Chunk processing callback (onData) is calling next() after the timeout limit. Increase the timeout limit or reduce chunkSize. |
Common causes:
onData
receives two arguments (chunk
andnext
) andnext()
callback has to be called within the acceptablechunkTimeout
(30 seconds by default) )
FlatfileError
Property | Value |
---|---|
code | FF-GE-00 |
debug | '' |
userMessage | An unknown issue has occurred |
Common causes:
- Flatfile was unable to process the request