#Parsing CSV from local storage

1 messages · Page 1 of 1 (latest)

jagged mural
#

Can someone guide me on how to load and parse csv file in remix? I had tried doing it using Papaparser (below is my implementation), but it doesn't work. What I want in my application is that, upon selecting a csv file from the local storage and clicking the submit button, I shall get an array of objects which I can further process.
It will be very helpful if someone can help me resolve this, thank you!

import { db } from '~/utils/db.server'
import React, { useState } from "react";
import Papa from "papaparse";
import {createTaskFromTaskRequest} from "~/routes/create/create-task.server";
import {parseMultipartFormData} from "@remix-run/node/parseMultipartFormData";
import {UploadHandler} from "@remix-run/node/formData";

const uploadHandler: UploadHandler = async ({ name, stream, filename }) => {
    await Papa.parse(filename, {
        complete: function(results) {
            console.log("Finished:", results);
            return results
        }
    });
};

export const action: ActionFunction = async ({ request }) => {
    console.log("im at the action");
    const body = await parseMultipartFormData(request, uploadHandler);

    console.log("body", body);
};


export default function FirstPage(){
    return (
        <Form method="post" action="/?index" encType="multipart/form-data">
            <ul>
                <input name="documents" type="file"/>
                <button type="submit">Submit</button>
            </ul>

        </Form>
    );
} ```
sinful pine
#

@jagged mural I am also trying to do the exact same thing!

undone cobalt
#

What doesn't work? Does it just never complete?

hallow stump
#

Correct me if I am wrong, but I believe that this simply cannot work because localStorage is only present on the client, while action gets invoked on the Server.

Because of this, there is no way for it to access the client-side localStorage.

undone cobalt
#

That's right. You could shim localStorage if all else fails

vital hamlet
#

Localstorage as in http database or “users computer”?

jagged obsidian
#

If you are trying to send csv data from a file that is on the user's computer, you can convert it to json (using csvtojson and then send it to your action using the useSubmit hook:

export default function FirstPage() {
  const [importFile, setImportFile] = useState<File>();
  const submit = useSubmit();

  const onFileChange = (e: React.FormEvent<HTMLInputElement>) => {
    if (e?.currentTarget?.files && e.currentTarget.files.length > 0) {
      setImportFile(e.currentTarget.files[0]);
    }
  };

  const readFileData = async () => {
    if (!importFile) {
      return "";
    }

    let formData = "";

    const readerPromise = new Promise((resolve) => {
      const reader = new FileReader();

      reader.onload = async (e: ProgressEvent<FileReader>) => {
        const csvData = e.target?.result;

        if (!csvData || typeof csvData !== "string") {
          return;
        }

        const jsonData = await csvToJson().fromString(csvData);

        formData = JSON.stringify(jsonData);

        resolve(null);
      };

      reader.readAsText(importFile);
    });

    await readerPromise;

    return formData;
  };

  const onSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
    e.preventDefault();

    if (importFile) {
      const formData = await readFileData();
      console.log(formData);
      submit(
        {
          formData,
        },
        {
          method: "post",
          action: "./firstPage",
        }
      );
    }
  };

  return (
    <Form method="post" onSubmit={onSubmit}>
      <ul>
        <input name="documents" type="file" onChange={onFileChange} />
        <button type="submit">Submit</button>
      </ul>
    </Form>
  );
}