PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Sunday, August 28, 2022

[FIXED] how to create api route that will send a CSV file to the frontend in Next.js

 August 28, 2022     csv, next.js, node.js, reactjs     No comments   

Issue

As far as I know (correct me if i'm wrong please) the flow of downloading a file should be that the frontend make a call to an api route and everything else is going on on the server.

My task was to read from firestore and write it to the CSV file, I populated the CSV file with the data and now when I try to send it to the frontend only thing that is in the file after the download it the first line containing headers name and email (the file that was written on my computer is correctly willed with the data). This is my route

import { NextApiHandler } from "next";
import fs from "fs";
import { stringify } from "csv-stringify";
import { firestore } from "../../firestore";
import { unstable_getServerSession } from "next-auth/next";
import { authOptions } from "./auth/[...nextauth]";

const exportFromFirestoreHandler: NextApiHandler = async (req, res) => {
  const session = await unstable_getServerSession(req, res, authOptions);

  if (!session) {
    return res.status(401).json({ message: "You must be authorized here" });
  }

  const filename = "guestlist.csv";
  const writableStream = fs.createWriteStream(filename);
  const columns = ["name", "email"];
  const stringifier = stringify({ header: true, columns });

  const querySnapshot = await firestore.collection("paprockibrzozowski").get();
  await querySnapshot.docs.forEach((entry) => {
    stringifier.write([entry.data().name, entry.data().email], "utf-8");
  });
  stringifier.pipe(writableStream);
  const csvFile = await fs.promises.readFile(
    `${process.cwd()}/${filename}`,
    "utf-8"
  );

  res.status(200).setHeader("Content-Type", "text/csv").send(csvFile);
};

export default exportFromFirestoreHandler;

since I await querySnapshot and await readFile I would expect that the entire content of the file would be sent to the frontend. Can you please tell me what am I doing wrong?

Thanks


Solution

The await on that forEach is most definitely not doing what you expect it to do, also you probably shouldn't use await and forEach together

Either switch to using the Sync API for the csv-stringify library or do something along these lines (assuming the first .get() actually contains the actual values from a promise):

[...]
  stringifier.pipe(writableStream);
  stringifier.on('finish', () => {
    const csvFile = await fs.promises.readFile(
       `${process.cwd()}/${filename}`,
        "utf-8"
     );
     res.status(200).setHeader("Content-Type", "text/csv").send(csvFile);
  });
  for (const entry of querySnapshot.docs) {
      stringifier.write([entry.data().name, entry.data().email], "utf-8");
  );
  stringifier.end();

[...]



Answered By - Nelloverflow
Answer Checked By - David Marino (PHPFixing Volunteer)
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

1,213,653

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © 2025 PHPFixing