# Export related data as CSV

This example shows you how to create a Smart Action `"Export orders as CSV"` that allows a user to download all the orders associated to a customer.

![](https://2793709227-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M0vHiS-1S9Hw3djvoTw%2F-MKaZ5sVyNygaGMayyLw%2F-MKaZ_wFP5H3ok_hAeeq%2Fcsv%20export%20of%20related%20data.gif?alt=media\&token=d34d62de-710a-4965-aa19-a56646f335a6)

## Requirements

* The [json2CSV](https://www.npmjs.com/package/json2csv) npm package

```javascript
$ npm install json2csv
```

## How it works

### Directory: /models

This directory contains:

* the `customers.js` file where the `customers` model is declared.
* the `orders.js` file where the `orders` model is declared&#x20;

{% code title="customers.js" %}

```javascript
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  const Customers = sequelize.define('customers', {
    firstname: {
      type: DataTypes.STRING,
    },
    lastname: {
      type: DataTypes.STRING,
    },
    email: {
      type: DataTypes.STRING,
    },
    createdAt: {
      type: DataTypes.DATE,
    },
    updatedAt: {
      type: DataTypes.DATE,
    },
  }, {
    tableName: 'customers',
    underscored: true,
    schema: process.env.DATABASE_SCHEMA,
  });

  Customers.associate = (models) => {
    Customers.hasMany(models.orders, {
      foreignKey: {
        name: 'customerIdKey',
        field: 'customer_id',
      },
      as: 'orders',
    });
  };

  return Customers;
};

```

{% endcode %}

{% code title="orders.js" %}

```javascript
module.exports = (sequelize, DataTypes) => {
  const { Sequelize } = sequelize;
  const Orders = sequelize.define('orders', {
    ref: {
      type: DataTypes.STRING,
      primaryKey: true,
      defaultValue: Sequelize.literal('nextval(orders_id_seq::regclass)'),
      allowNull: false,
    },
    shippingStatus: {
      type: DataTypes.ENUM(['In transit', 'Shipped', 'Being processed', 'Ready for shipping']),
    },
    createdAt: {
      type: DataTypes.DATE,
    },
    updatedAt: {
      type: DataTypes.DATE,
    },
    beingProcessedAt: {
      type: DataTypes.DATE,
    },
    readyForShippingAt: {
      type: DataTypes.DATE,
    },
    inTransitAt: {
      type: DataTypes.DATE,
    },
    shippedAt: {
      type: DataTypes.DATE,
    },
  }, {
    tableName: 'orders',
    underscored: true,
    schema: process.env.DATABASE_SCHEMA,
  });

  Orders.associate = (models) => {
    Orders.belongsTo(models.customers, {
      foreignKey: {
        name: 'customerIdKey',
        field: 'customer_id',
      },
      as: 'customer',
    });
  };

  return Orders;
};

```

{% endcode %}

### Directory: /forest

This directory contains the `customers.js` file where the smart action `Export orders as CSV` is declared.&#x20;

{% hint style="info" %}
You need to set the attribute `download` as **true** to enable a download
{% endhint %}

{% code title="customers.js" %}

```javascript
const { collection } = require('forest-express-sequelize');

collection('customers', {
  actions: [
    {
      name: 'Export orders as CSV',
      type: 'single',
      download: true,
    },
  ],
  fields: [],
  segments: [],
});

```

{% endcode %}

### Directory: /utils

This directory contains a `csv-exporter.js` file where the method to export the orders as CSV is declared.

{% hint style="info" %}
The `json2csv` package allows you to format the data exported. It can be useful in particular when you have fields of the type JSON that you may want to unwind. You can take a look at the json2csv documentation [here](https://www.npmjs.com/package/json2csv).
{% endhint %}

{% code title="csv-exporter.js" %}

```javascript
const { parse } = require('json2csv');

function exportCustomerOrdersAsCSV(response, data) {
  // set the response header to tell the browser to expect a csv
  response.setHeader('Content-Type', 'text/csv');
  response.setHeader('Content-Disposition', `attachment; filename=cust-${data[0].customerIdKey}-orders.csv`);
  response.setHeader('Access-Control-Expose-Headers', 'Content-Disposition');
  // list the fields of the orders that you want to display as columns of the csv
  const fields = [
    'ref',
    'shippingStatus',
    'createdAt',
    'UpdatedAt',
    'beingProcessedAt',
    'readyForShippingAt',
    'inTransitAt',
    'shippedAt',
  ];
  // convert the array of records into a csv
  try {
    const csv = parse(data, { fields });
    return response.send(csv);
  } catch (err) {
    return response.status(500).json({ err });
  }
}

module.exports = exportCustomerOrdersAsCSV;
```

{% endcode %}

###

### Directory: /routes

This directory contains the `customers.js` file where the logic of the smart action is implemented.

{% code title="customers.js" %}

```javascript
const express = require('express');
const { PermissionMiddlewareCreator } = require('forest-express-sequelize');
const { orders } = require('../models');
const exportCustomerOrdersAsCSV = require('../utils/csv-exporter');


const router = express.Router();
const permissionMiddlewareCreator = new PermissionMiddlewareCreator('customers');

router.post('/actions/export-orders-as-csv', permissionMiddlewareCreator.smartAction(), async (req, res) => {
  // Get the current record id
  const recordId = req.body.data.attributes.ids[0];
  // get an array of records that are the orders of the customer and export them
  return orders.findAll({ where: { customerIdKey: recordId } })
    .then((data) => exportCustomerOrdersAsCSV(res, data));
});

module.exports = router;

```

{% endcode %}
