Pup

v1.x

AccountsExporting Data

Pup includes the ability for users to export their data as a .zip file containing individual .txt files for each of their documents stored in the Documents collection. This is provided mostly as an example for developers, giving you an action pattern that you can modify for your own use to add additional export layers for your users.

Inside of that action, we provide three methods getDocuments which retrieves all of the users documents data, addDocumentsToZip which populates the .zip file with individual .txt files for each of the user's documents and generateZip which finalizes the .zip file and returns it to us as a base64 string that we can send back to the client.

By default, the export functionality is included in the /profile page of the app for all users. To handle the export, Pup relies on the b64-to-blob package to convert the base64 string we received from the server into a file blob which is then passed to the file-saver NPM package's .saveAs() method to perform the download to the user's computer.

/imports/api/Users/server/export-data.js
/* eslint-disable consistent-return */

import JSZip from 'jszip';
import Documents from '../../Documents/Documents';

let action;

const generateZip = (zip) => {
  try {
    zip.generateAsync({ type: 'base64' })
      .then(content => action.resolve(content));
  } catch (exception) {
    throw new Error(`[exportData.generateZip] ${exception.message}`);
  }
};

const addDocumentsToZip = (documents, zip) => {
  try {
    documents.forEach((document) => {
      zip.file(`${document.title}.txt`, `${document.title}\n\n${document.body}`);
    });
  } catch (exception) {
    throw new Error(`[exportData.addDocumentsToZip] ${exception.message}`);
  }
};

const getDocuments = (userId) => {
  try {
    return Documents.find({ owner: userId }).fetch();
  } catch (exception) {
    throw new Error(`[exportData.getDocuments] ${exception.message}`);
  }
};

const exportData = ({ userId }, promise) => {
  try {
    action = promise;
    const zip = new JSZip();
    const documents = getDocuments(userId);
    addDocumentsToZip(documents, zip);
    generateZip(zip);
  } catch (exception) {
    action.reject(exception.message);
  }
};

export default options =>
  new Promise((resolve, reject) =>
    exportData(options, { resolve, reject }));