How to send `application/zip` in react-native

1.2k Views Asked by At

I want to generate a zip file and then POST it up. I am trying to leverage this lib JSZip to create a zip with several files in it. Here is what I have right now.

handlePendingItems = async (routeId: number) => {
    try {
      await dbClient.addLogLine(`Need to delete photos.`);
      const [debugLogs, pendingTasks, pendingUploads] = await this.getPendingItems();
      const dbVersion = await dbClient.getUserSchemaVersion();
      let appInfo = `Database Version = ${dbVersion}\n`;
      appInfo += `App Version = ${version}`;
      const zip = new JSZip();
      zip.file('app-info.txt', appInfo);
      if (debugLogs.length) {
        const debugLogsCsv = convertDataToCSV(debugLogs);
        zip.file('debug-logs.csv', debugLogsCsv);
      }
      if (pendingTasks.length) {
        const pendingTasksCsv = convertDataToCSV(pendingTasks);
        zip.file('pending-tasks.csv', pendingTasksCsv);
      }
      if (pendingUploads.length) {
        const pendingUploadsCsv = convertDataToCSV(pendingUploads);
        zip.file('pending-uploads.csv', pendingUploadsCsv);
      }
      const test = await zip.generateAsync({ type: 'binarystring' });
      console.log(test);
      const res = PhotoService.uploadLogs(routeId, test);

      // const zipFile = await zip.generateAsync({
      //   type: 'blob',
      //   compression: 'DEFLATE',
      //   compressionOptions: {
      //     level: 9
      //   }
      // });
    } catch (error) {
      console.log(error);
    }
  };

I can't use the type: 'blob' in react-native, it throws an error as unsupported on this platform. That being said I am trying to use other types to pass to react-native-fetch-blob. To be posted via the following code.

  uploadLogs(driverRouteId: number, logs: string) {
    const store = getStore();
    const token = store.getState()?.auth?.token || '';

    return new Promise((resolve, reject) => {
      RNFetchBlob.fetch(
        'POST',
        `${API_HOST}driver/route/${driverRouteId}/logs`,
        {
          'Content-Type': 'application/zip',
          Authorization: `Bearer ${token}`
        },
        logs
      ).then(
        (res) => {
          console.log(res);
          resolve(res);
        },
        (err) => {
          console.log(err);
          debugger;
          reject(err);
        }
      );
    });
  }

I read that fetch blob will attempt to parse base64 string if the content-encoding is a specific type which in this case has to be application/zip (so no parsing in this case) so I am trying to call generateAsync with type string however, the zip the file the server stores is in an unsupported format. How can I generate the zip file containing the three csv files and the txt file and send it using either fetch blob or just plain axios in react-native.

1

There are 1 best solutions below

0
Tzvetlin Velev On BEST ANSWER

Figured out a solution using a different library to zip.

npm install react-native-zip-archive --save
npm install react-native-fs --save
npm install rn-fetch-blob --save
import RNFetchBlob from 'rn-fetch-blob';
import { zip } from 'react-native-zip-archive';
import RNFS from 'react-native-fs';

const pathsToZip = [];
const zipPath = `${RNFS.DocumentDirectoryPath}/test.zip`;
const appInfo = 'App info string to put in txt file'
const appInfoPath = RNFS.DocumentDirectoryPath + '/appInfo.txt';
await RNFS.writeFile(appInfoPath, appInfo, 'utf8');
pathsToZip.push(appInfoPath);
await zip(pathsToZip, zipPath);

await uploadLogs(zipPath) {
    return new Promise((resolve, reject) => {
      RNFetchBlob.fetch(
        'POST',
        `postpath`,
        {
          'Content-Type': 'application/zip',
        },
        RNFetchBlob.wrap(zipPath)
      ).then(
        (res) => {
          console.log(res);
          resolve(res);
        },
        (err) => {
          console.log(err);
          debugger;
          reject(err);
        }
      );
    });
}