All Collections
Flatfile Data Exchange Platform
Guides
How to Automatically Close the iframe of an Embedded Importer
How to Automatically Close the iframe of an Embedded Importer
Elisa Dinsmore avatar
Written by Elisa Dinsmore
Updated over a week ago

Client-side embed, server-side space configuration, server-side listeners.

In this setup, the client-side is just creating a space and opening it inside the iframe. Control of space configuration and listeners are all running server-side in Flatfile’s cloud platform.

We expect that the user will click the “Submit” button in the workbook and after the submission process is complete, the iframe will close and the user will be returned to the parent page.

Define the submit action in the server-side “space:configure” listener.

listener
.filter({ job: "space:configure" })
.on("job:ready", async (event: FlatfileEvent) => {
const { spaceId, environmentId, jobId } = event.context;
try {
await api.jobs.ack(jobId, {
info: "Getting started.",
progress: 10,
});


await api.workbooks.create({
spaceId,
environmentId,
name: "Import Data",
labels: ["pinned"], // makes this workbook the first one in the list
settings: { trackChanges: true },
sheets: [contactSheet],
actions: [
{
label: "Submit",
operation: "submit",
description: "Ready to submit your data?",
mode: "foreground",
primary: true,
confirm: true,
constraints: [{ type: 'hasData' }]
}
]
})


await api.jobs.complete(jobId, {
outcome: {
message: "Your Space was created. Let's get started.",
acknowledge: true,
},
});


} catch (error) {
console.error("Error:", error.stack);


await api.jobs.fail(jobId, {
outcome: {
message: "Creating a Space encountered an error. See Event Logs.",
acknowledge: true,
},
});
}
});

Notice that the operation of the action is “submit”. This is what we will expect to see on the client-side when it’s time to close the iframe.

When the user clicks the “Submit” button, a server-side listener will catch this event:

listener
.filter({ job: "workbook:submit" })
.on("job:ready", async (event: FlatfileEvent) => {
const { workbookId, jobId, spaceId } = event.context;


try {
await api.jobs.ack(jobId, {
info: "Getting started.",
progress: 10,
});


// Do something with the data


await api.jobs.complete(jobId, {
outcome: {
message: "Your data has been submitted.",
next: {
type: "wait"
}
},
})


// close the iframe automatically
// await api.jobs.ackOutcome(jobId);


} catch (error) {
await api.jobs.fail(jobId, {
outcome: {
message: `${error}`,
},
});
}
});

In the api.jobs.complete call, we specify in the “outcome” block that the UI will wait for the user to click the continue button. When the user clicks the continue button, we want the client-side to close the iframe. Alternatively, you can automatically close the iframe by acknowledging the outcome with the api.jobs.ackOutcome call. Just uncomment that line. Since this will happen immediately, the user will never see the dialog box with the “Your data has been submitted.” text.

In either case, the client-side still needs to be configured to close the iframe correctly.

Whether using React, JS, Vue, or Angular, there will be a closeSpace object in your client-side space definition. Here’s an example in JavaScript:

   closeSpace: {
operation: "submit",
onClose: () => {
setShowSpace(false)
}
},

Note that the operation must match the operation used in the action definition from above. This is what ties the server-side code to the client-side. As long as the operation name matches, the client-side will close the iframe as expected.

Did this answer your question?