Woodshop for old agent generation
Try the new agent generation
  • What is woodshop
  • How to's
    • Smart Relationship
      • GetIdsFromRequest
    • Smart views
      • Display a calendar view
      • Create a custom tinder-like validation view
      • Create a custom moderation view
      • Create a dynamic calendar view for an event-booking use case
    • Configure environment variables
      • NodeJS/Express projects
    • Elasticsearch Integration
      • Interact with your Elasticsearch data
      • Elasticsearch service/utils
      • Another example
    • Zendesk Integration
      • Authentication, Filtering & Sorting
      • Display Zendesk tickets
      • Display Zendesk users
      • View tickets related to a user
      • Bonus: Direct link to Zendesk + change priority of a ticket
    • Dwolla integration
      • Display Dwolla customers
      • Display Dwolla funding sources
      • Display Dwolla transfers
      • Link users and Dwolla customers
      • Dwolla service
    • Make filters case insensitive
    • Use Azure Table Storage
    • Create multiple line charts
    • Create Charts with AWS Redshift
    • View soft-deleted records
    • Send Smart Action notifications to Slack
    • Authenticate a Forest Admin API against an OAuth protected API Backend
    • Translate your project into TypeScript
      • V8
        • Migrate Mongoose files
        • Migrate Sequelize files
      • v7
        • Migrate Mongoose files
        • Migrate Sequelize files
      • v6
    • Geocode an address with Algolia
    • Display/edit a nested document
    • Send an SMS with Zapier
    • Hash a password with bcrypt
    • Display a customized response
    • Search on a smart field with two joints
    • Override the count route
    • Make a field readOnly with Sequelize
    • Hubspot integration
      • Create a Hubspot company
      • Display Hubspot companies
    • Impersonate a user
    • Import data from a CSV file
    • Import data from a JSON file
    • Load smart fields using hook
    • Pre-fill a form with data from a relationship
    • Re-use a smart field logic
    • Link to record info in a smart view
    • Display data in html format
    • Upload files to AWS S3
    • Display AWS S3 files from signed URLs
    • Prevent record update
    • Display, search and update attributes from a JSON field
    • Add many existing records at the same time (hasMany-belongsTo relationship)
    • Track users’ logs with morgan
    • Search on relationship fields by default
    • Export related data as CSV
    • Run automated tests
  • Forest Admin Documentation
Powered by GitBook
On this page
  • Requirements
  • How it works
  • Directory: /models
  • Directory: /forest
  • Directory: /utils
  • Directory: /routes

Was this helpful?

  1. How to's

Export related data as CSV

PreviousSearch on relationship fields by defaultNextRun automated tests

Last updated 4 years ago

Was this helpful?

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.

Requirements

$ 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

customers.js
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;
};
orders.js
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;
};

Directory: /forest

This directory contains the customers.js file where the smart action Export orders as CSV is declared.

You need to set the attribute download as true to enable a download

customers.js
const { collection } = require('forest-express-sequelize');

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

Directory: /utils

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

csv-exporter.js
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;

Directory: /routes

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

customers.js
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;

The npm package

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 .

json2CSV
here