Flatfile

How to Create an Angular CSV Importer in 2 minutes

Mark Pieszak

Posted 2/25/2021

Angular is a JavaScript framework and application development platform for creating efficient and sophisticated single-page apps. 

With Angular applications, there are several ways to upload CSV files. Now, with Flatfile, the data import process is much simpler!

Introducing the brand new Flatfile Angular component.

The new Flatfile Angular component handles all of the heavy lifting, letting companies import and manage CSV file data in minutes. Now let’s dig in and we’ll show you how.

Before we get started, let’s make sure to have a license key to use the Flatfile portal. If you don’t have one already, you can sign up for it here.

Getting Started with Flatfile and Angular:

First, let’s get the new Flatfile angular library installed in our applications:

npm install @flatfile/angular --save

or 

yarn add @flatfile/angular


Now let’s head over to our AppModule (or whatever module you want to upload a CSV in) and import the FlatfileAdapterModule.

import { FlatfileAdapterModule } from '@flatfile/angular';

// Add to your Modules imports: []
imports: [
  FlatfileAdapterModule
]

Great! Now we’re able to use the new <flatfile-button /> anywhere in this module's components.

Let’s head over to a component and add it, along with a few optional properties and methods that can be passed down to the Flatfile library.

To get started with the component, the only required Inputs that need to be passed down are licenseKey (a String), settings (an Object), and customer (an Object containing userId which is required).

You can find more information on those properties, and all of the other optional Input methods and Output methods that can come from the Flatfile adapter here

@Component({
  template: `
    <flatfile-button
      [licenseKey]="licenseKey"
      [settings]=”settings”
      [customer]=”customer”>
    </flatfile-button>
  `
}) export class BasicDemoComponent {
  customer = { userId: '12345' };
  licenseKey = 'LICENSE_KEY_HERE';
}

Just like that, we have a very basic and default Flatfile adapter behavior in our applications!

But what if we want to customize this a bit further? Let’s take a look at some of the other optional properties and methods that can be passed down as Inputs, and some Output methods we can hook into the component with.

In the next example, we’re going to pass down a few things.

A settings Object, which will let Flatfile know some information about the types of columns/fields we’re expecting from our CSV imports.

A fieldHooks object, that will run on the initialization of imports (between matching & review stages), and in our case we’ll setup a fieldHooks rule for the email field. With fieldHooks, we can do setup validation for columns, or even formatting data within a column (take for example, formatting a date column to transform the data in a specific way).

Next we’re going to pass down 3 methods to hook into lifecycle events in our import process. These Input methods we’ll be hooking into are: [onData], [onRecordInit], and [onRecordChange]. As the names imply, these are methods that we can pass down the Flatfile importer to fire off when these events occur.

One important thing to note here is that since these methods we pass down will be invoked inside of the library, it is crucial that we pass down our methods utilizing the JavaScript .bind(this) method, so that the methods closure context is our current class here (MyDemoComponent). This ensures we avoid errors if we’re trying to access properties/methods/dependencies within our component here.

Lastly we’re showing one of the optional Output methods available to us, and this is (cancel), as the name suggests, we can fire off our own method here, whenever a user cancels or exits the import process entirely.

@Component({
  template: `
    <flatfile-button
      [customer]="customer"
      [licenseKey]="licenseKey"
      [settings]="settings"
      [fieldHooks]="fieldHooks"
      [onData]="onData.bind(this)"
      [onRecordInit]="onRecordInit.bind(this)"
      [onRecordChange]="onRecordChange.bind(this)"
      (cancel)="onCancel()">
      This text is coming from the end-user of this component
    </flatfile-button>
  `
}) export class MyDemoComponent {
  
  customer = { userId: '12345' };
  licenseKey = 'LICENSE_KEY_HERE';
  settings = {
    type: 'test import',
    fields: [
      { label: 'Name', key: 'name' },
      { label: 'Email', key: 'email' },
    ],
  };


  fieldHooks: Record<string, FieldHookCallback> = {
    email: (values) => {
      return values.map(([item, index]) => [
        { value: item + '@', info: [{message: 'added @ after the email', level: 'warning'}] },
        index
      ]);
    }
  };

  /*
   * @Input() methods
   */
  onData(results: FlatfileResults): Promise<string> {
    let errorState = false;

    return new Promise((resolve, reject) => {
      setTimeout(() => {
        if (errorState) {
            reject('rejected - this text is controlled by the end-user');
            errorState = false;
          } else {
            resolve('Flatfile upload successful - this text is controlled by the end-user');
          }
      }, 3000);
    });
  }

  onRecordInit(record: ScalarDictionaryWithCustom, index: number): IDataHookResponse | Promise<IDataHookResponse> {
    return {
      email: {
        value: record.email + '@',
        info: [{ message: 'added @ on init', level: 'info' }]
      }
    };
  }

  onRecordChange(record: ScalarDictionaryWithCustom, index: number): IDataHookResponse | Promise<IDataHookResponse> {
    return {
      email: {
        value: record.email + '#',
        info: [{ message: 'added # on change', level: 'warning' }]
      }
    };
  }

  /*
   * @Output() handlers
   */
  onCancel(): void {
    console.log('canceled!');
  }
}

Just like that, in minutes, we set up CSV import functionality and can harness the power of  Flatfile to handle all of our CSV data needs.

To view the Flatfile Angular importer in action, check out the CodeSandbox demo here

To view the code for the Flatfile Angular component, find it on Github.

The data import experience is easier than ever
Start for free