Error: Creating blobs from ‘ArrayBuffer’ and ‘ArrayBufferView’ are not supported in ReactNative

  Kiến thức lập trình

I’m encountering an error while working on my React Native application.

When I attempt to transform the HTML content of a page into a PDF for export and client email, I receive the following error:
Error: Creating blobs from 'ArrayBuffer' and 'ArrayBufferView' are not supported.

The backend API is built in ASP.NET Core 8. The page I am trying to convert to PDF contains a client’s signature, and the application will be used on both Android and iOS devices.

This is the page that I want to export:

import {
  View,
  Text,
  Image,
  StyleSheet,
  ScrollView,
  TextInput,
  Button,
  Alert,
  TouchableOpacity,
  Modal,
  Switch,
} from "react-native";
import { useNavigation } from "@react-navigation/native";
import { useAppContext } from "../../AppContext";
import { getCurrentDate } from "../helpers/DateHelper";
import SignatureSpace from "../components/SignatureSpace";
import { error } from "pdf-lib";

const DataScreen = () => {
  const {
    cardHolderName,
    userID,
    email,
    phoneNumber,
    address,
    locality,
    postalCode,
    county,
    barcodeData,
    registrationType,
    fiscalCode,
    globalRegistrationType,
    companyNameData,
  } = useAppContext();

  const navigation = useNavigation();
  const pageRefAll = useRef(null);
  const signatureRef = useRef(null);
  const [signatureData, setSignatureData] = useState(null);
  const [isButtonEnabled, setIsButtonEnabled] = useState(false);
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [form, setForm] = useState({
    date: "",
    communicationChannel: [],
  });

  // .............

  useEffect(() => {
    const allFieldsCompleted = signatureData !== null;
    setIsButtonEnabled(allFieldsCompleted);
  }, [signatureData]);

  const sendCardToEmail = async () => {
    try {
      let emailBody =
        `Hello, ${cardHolderName}nHere are your registration details:n` +
        `Email: ${email}n` +
        `Phone Number: ${phoneNumber}n` +
        `Address: ${address}, ${postalCode}, ${locality}, ${county}`;

      if (registrationType === "business") {
        emailBody += `nFiscal Code: ${fiscalCode}`;
      }

      const emailDetails = {
        name: cardHolderName,
        fiscalCode: fiscalCode,
        email: email,
        phoneNumber: phoneNumber,
        barcode: barcodeData,
        registrationType: registrationType,
        address: `${address}, ${postalCode}, ${locality}, ${county}`,
        body: emailBody,
      };

      const response = await fetch(
        "https://flowermarketapi.azurewebsites.net/Clients/send-email",
        {
          method: "POST",
          headers: {
            "Content-Type": "application/json",
          },
          body: JSON.stringify(emailDetails),
        }
      );

      if (response.ok) {
        console.log("Email sent successfully!");
      } else {
        console.error("Failed to send email. " + (await response.text()));
      }
    } catch (error) {
      console.error("Error sending email", error);
    }
  };

  const handleSubmit = async () => {
    if (!isButtonEnabled) return;
    // sendCardToEmail();
    // navigation.navigate("Card");

    const gdprHtmlString = `
    <div class="dataScreen">
>!     here is the text that will be sent to API in order to convert and send via email
    </div>`;
    console.log("GDPR " + { companyNameData } + ".pdf");
    const blob = dataURItoBlob(signatureData);
    console.log("signatureData", signatureData);
    const formData = new FormData();
    console.log("FormData", FormData);

    try {
      formData.append("model", gdprHtmlString);
      console.log("model", gdprHtmlString); // here is stop the application and not move forward
      formData.append("signature", blob);
      console.log("signature", blob);
      formData.append("userID", userID);
      console.log("userID", userID);
      formData.append("fileNameftp", companyNameData);
      console.log("fileNameftp", companyNameData);
    } catch (error) {
      console.log("Error during creating PDF: ", error);
    }

    try {
      // Send the request with both form data and JSON data
      const response1 = await fetch(
        "https://flowermarketapi.azurewebsites.net/api/fileupload/export",
        {
          method: "POST",
          body: formData,
        }
      );

      if (response1.ok) {
        console.log("response ok");
      }
    } catch (error) {
      console.log("Error during loading: ", error);
    }

    try {
      sendCardToEmail();
      navigation.navigate("Card");
    } catch (error) {
      console.error("Error during submission: ", error);
      Alert.alert(
        "Error",
        "There was an error during submission: " + error.message
      );
    }
  };

  function dataURItoBlob(dataURI) {
    const byteString = atob(dataURI.split(",")[1]);
    const mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0];
    const ab = new ArrayBuffer(byteString.length);
    const ia = new Uint8Array(ab);
    for (let i = 0; i < byteString.length; i++) {
      ia[i] = byteString.charCodeAt(i);
    }
    return new Blob([ab], { type: mimeString });
  }

  return (
    <ScrollView contentContainerStyle={styles.dataScreen}>
      <View style={styles.dataContainer} ref={pageRefAll}>
        <View style={styles.dataHeader}>
          <Image
            source={require("../../assets/logo-dark 600.png")}
            style={styles.dataLogo}
            resizeMode="contain"
            onError={(error) => console.log("Image load error: ", error)}
            onLoad={() => console.log("Image loaded successfully")}
          />
          <Text style={styles.companyName}>FLOWERS MARKET HOLLAND S.R.L.</Text>
  
>!    .............  the text that will be sent to the client    .................
>! ..........................
>! ..........................
            <View style={styles.signatureContainer}>
              <View style={styles.signatureSection}>
                <Text style={styles.labelTop}>{getCurrentDate(".")}</Text>
                <Text style={styles.labelTop}>{companyNameData}</Text>
                <Text style={styles.labelTop}>{cardHolderName}</Text>

                <TouchableOpacity
                  style={styles.clientSignature}
                  onPress={handleSignatureOpen}
                >
                  {signatureData ? (
                    <Image
                      source={{ uri: signatureData }}
                      style={{ width: "100%", height: "100%" }}
                    />
                  ) : (
                    <Text>Sign Here</Text>
                  )}
                </TouchableOpacity>
              </View>

              {signatureData && (
                <View style={styles.signatureContainer}>
                  {/* <Text>Signature Captured:</Text> */}
                  <Image
                    source={{ uri: signatureData }}
                    style={styles.signatureImage}
                  />
                </View>
              )}

              <Modal
                visible={isModalVisible}
                animationType="slide"
                onRequestClose={handleSignatureClose}
              >
                <SignatureSpace
                  ref={signatureRef}
                  onSave={handleSignatureSave}
                  onClose={handleSignatureClose}
                />
              </Modal>
            </View>
          </View>
        </View>

        
        <TouchableOpacity
          style={[
            styles.acceptButton,
            !isButtonEnabled && styles.disabledButton,
          ]}
          onPress={handleSubmit}
          disabled={!isButtonEnabled}
        >
          <Text style={styles.buttonText}>Accept and Continue</Text>
        </TouchableOpacity>
      </View>
    </ScrollView>
  );
};

The package-json look like this:

  "name": "my-project",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "expo start --dev-client",
    "android": "expo run:android",
    "ios": "expo run:ios",
    "web": "expo start --web"
  },
  "dependencies": {
    "@kichiyaki/react-native-barcode-generator": "^0.6.7",
    "@react-native-masked-view/masked-view": "^0.3.1",
    "@react-navigation/bottom-tabs": "^6.5.20",
    "@react-navigation/native": "^6.1.17",
    "@react-navigation/stack": "^6.3.29",
    "expo": "~51.0.9",
    "expo-dev-client": "~4.0.15",
    "expo-status-bar": "~1.12.1",
    "pdf-lib": "^1.17.1",
    "react": "18.2.0",
    "react-native": "0.74.1",
    "react-native-barcode-builder": "^2.0.0",
    "react-native-barcode-creator": "^0.1.7",
    "react-native-gesture-handler": "^2.16.2",
    "react-native-image-picker": "^7.1.2",
    "react-native-safe-area-context": "^4.10.3",
    "react-native-screens": "^3.31.1",
    "react-native-signature-canvas": "^4.7.2",
    "react-native-svg": "^15.3.0",
    "react-native-view-shot": "^3.8.0",
    "react-native-webview": "^13.8.6"
  },
  "devDependencies": {
    "@babel/core": "^7.20.0"
  },
  "private": true
}````

I try to put more console logs in order to see where it stop, and the handleSubmit function is stop here:
````console.log("model", gdprHtmlString);````

The app runs on a tablet emulator from Android Studio because the client requires this technology. I need help finding a solution to send the client the page's content in a PDF with his signature.

New contributor

Marco Chitu is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.

LEAVE A COMMENT