react-native-esc-pos-printer icon indicating copy to clipboard operation
react-native-esc-pos-printer copied to clipboard

(NOBRIDGE) ERROR Error: , js engine: hermes

Open Mehul175 opened this issue 7 months ago • 9 comments

Description

Project Version Informations

System: OS: macOS 15.4.1 CPU: (8) arm64 Apple M2 Memory: 467.77 MB / 16.00 GB Shell: version: "5.9" path: /bin/zsh Binaries: Node: version: 20.13.1 path: ~/.nvm/versions/node/v20.13.1/bin/node Yarn: version: 3.6.4 path: /opt/homebrew/bin/yarn npm: version: 10.8.3 path: ~/.nvm/versions/node/v20.13.1/bin/npm Watchman: version: 2025.06.30.00 path: /opt/homebrew/bin/watchman Managers: CocoaPods: version: 1.14.3 path: /Users/ashokdudhat/.rvm/gems/ruby-3.1.0/bin/pod SDKs: iOS SDK: Platforms: - DriverKit 24.4 - iOS 18.4 - macOS 15.4 - tvOS 18.4 - visionOS 2.4 - watchOS 11.4 Android SDK: Not Found IDEs: Android Studio: 2024.3 AI-243.25659.59.2432.13423653 Xcode: version: 16.3/16E140 path: /usr/bin/xcodebuild Languages: Java: version: 17.0.16 path: /opt/homebrew/opt/openjdk@17/bin/javac Ruby: version: 3.1.0 path: /Users/ashokdudhat/.rvm/rubies/ruby-3.1.0/bin/ruby npmPackages: "@react-native-community/cli": installed: 15.0.1 wanted: 15.0.1 react: installed: 19.0.0 wanted: 19.0.0 react-native: installed: 0.78.2 wanted: 0.78.2 react-native-macos: Not Found npmGlobalPackages: "react-native": Not Found Android: hermesEnabled: true newArchEnabled: false iOS: hermesEnabled: true newArchEnabled: true

Code:-

import {
  Keyboard,
  FlatList,
  StyleSheet,
  View,
  TouchableOpacity,
  ActivityIndicator,
} from "react-native";
import React, { useEffect, useRef, useState } from "react";
import { useNavigation, useRoute } from "@react-navigation/native";
import {
  usePrintersDiscovery,
  Printer,
  PrinterConstants,
} from "react-native-esc-pos-printer";
import Print from "../../../assets/svg/print";
import LeftArrow from "../../../assets/svg/leftArrow";

import _styles from "./style";
import {
  Header,
  Input,
  Layout,
  EmptyList,
  Text,
  useToast,
  Button,
} from "../../../components";
import MenuImg from "../../../assets/svg/menuImg";
import { useTheme } from "../../../utils/Theming";
import { getHeight, moderateScale } from "../../../utils/Constant";
import { useTranslation } from "react-i18next";
import { useDispatch, useSelector } from "react-redux";
import {
  setCurrentPrinter,
  setNoOfReceipts,
} from "../../../redux/actions/appAction";
import CheckMark from "../../../assets/svg/checkMark";
import { hasWritePermission } from "../../../utils/Helper";

const PrinterSetting = ({ route }) => {
  const { start, stop, isDiscovering, printers } = usePrintersDiscovery();
  const theme = useTheme();
  const styles = _styles(theme);
  const comingFrom = route?.params?.comingFrom;
  const navigation = useNavigation();
  const { t } = useTranslation();
  const dispatch = useDispatch();

  const numberOfReciepts = useSelector((state) => state.app.noOfReceipts);
  const [noOfPrint, setNoOfPrint] = React.useState(numberOfReciepts.toString());
  const isprintRef = useRef(null);

  useEffect(() => {
    start();
    return () => stop(); // Stop discovery when component unmounts
  }, []);

  useEffect(() => {
    setNoOfPrint(numberOfReciepts.toString());
  }, [numberOfReciepts]);

  const handleSearchPress = () => {
    if (!isDiscovering) {
      start();
    }
  };

  const RenderItem = ({ item, index }) => {
    return <RenderPrinter item={item} />;
  };

  const handleNumberofPrintKey = (value) => {
    setNoOfPrint(value);
    if (value) {
      if (!/^\d+$/.test(value)) {
        toast?.showToast({
          type: "error",
          title: null,
          subtitle: t("number_validation"),
          duration: 3000,
          noIcon: true,
        });
      } else {
        const num = Number(value); // Convert to number
        // Check if in range 0-5
        if (num >= 0 && num <= 5) {
        } else {
          toast?.showToast({
            type: "error",
            title: null,
            subtitle: t("0_to_5_raneg_validation"),
            duration: 3000,
            noIcon: true,
          });
        }
      }
    }
  };

  const onPressSave = () => {
    if (!hasWritePermission(t)) {
      toast?.showToast({
        type: "error",
        title: t("permission_error"),
        subtitle: null,
        duration: 1000,
        noIcon: true,
      });
      return;
    }
    if (noOfPrint) {
      if (!/^\d+$/.test(noOfPrint)) {
        toast?.showToast({
          type: "error",
          title: null,
          subtitle: t("number_validation"),
          duration: 3000,
          noIcon: true,
        });
      } else {
        const num = Number(noOfPrint); // Convert to number
        // Check if in range 0-5
        if (num >= 0 && num <= 5) {
          dispatch(setNoOfReceipts(num));
          toast?.showToast({
            type: "success",
            title: null,
            subtitle: t("no_of_receipts_update_success"),
            duration: 3000,
            noIcon: true,
          });
        } else {
          toast?.showToast({
            type: "error",
            title: null,
            subtitle: t("0_to_5_raneg_validation"),
            duration: 3000,
            noIcon: true,
          });
        }
      }
    }
  };

  return (
    <Layout>
      <Header
        leftIcon={
          comingFrom == "sideDrawer" ? (
            <MenuImg
              width={moderateScale(24)}
              height={moderateScale(24)}
              color={styles.headerIconColor}
            />
          ) : (
            <LeftArrow
              width={moderateScale(24)}
              height={moderateScale(24)}
              color={styles.headerIconColor}
            />
          )
        }
        leftAction={() =>
          comingFrom == "sideDrawer"
            ? navigation.openDrawer()
            : navigation.goBack()
        }
        title={"printer_setting"}
      />
      <View style={styles.container}>
        <View style={styles.receiptSettings}>
          <Text type="M16" style={{ marginTop: moderateScale(5) }}>
            {t("no_of_receipts")}
          </Text>
          <View style={{ flexDirection: "row", gap: moderateScale(15) }}>
            <Input
              placeholder={t("enter_number")}
              value={noOfPrint}
              onChange={handleNumberofPrintKey}
              keyboardType={"number-pad"}
              spellCheck={false}
              returnKeyType="done"
              onSubmitEditing={Keyboard.dismiss}
              ref={isprintRef}
              style={{ flex: 1 }}
            />
            <Button
              title={"save"}
              style={{
                flex: 1,
                marginTop: 0,
                marginVertical: 0,
                alignSelf: "center",
                flexGrow: 1,
                height: getHeight(58),
              }}
              onPress={onPressSave}
            />
          </View>
        </View>
        <View style={styles.printerConnection}>
          <Text type="M16" style={{ marginVertical: moderateScale(5) }}>
            {t("printer_connection")}
          </Text>
          <TouchableOpacity
            disabled={isDiscovering}
            onPress={handleSearchPress}
            style={styles.btnStyle}
          >
            <Text style={styles.btnTextStyle} type="M14">
              {isDiscovering
                ? t("searching_nearby_printer")
                : t("search_nearby_printer")}
            </Text>
          </TouchableOpacity>

          {!isDiscovering ? (
            printers.length > 0 ? (
              <FlatList
                ListHeaderComponent={RenderHeaderComponent}
                keyExtractor={(item, index) => index.toString()}
                data={printers}
                renderItem={RenderItem}
              />
            ) : (
              <EmptyList
                text={"no_printers_available"}
                Icon={Print}
                style={{ marginVertical: moderateScale(150) }}
              />
            )
          ) : (
            <View style={{ justifyContent: "center", flex: 1 }}>
              <ActivityIndicator
                color={theme["color-primary-500"]}
                size={"large"}
              />
            </View>
          )}
        </View>
      </View>
    </Layout>
  );
};

export default PrinterSetting;

const RenderPrinter = ({ item }) => {
  const theme = useTheme();
  const styles = _styles(theme);
  const { t } = useTranslation();
  const dispatch = useDispatch();
  const toast = useToast();

  const currentPrinter = useSelector((state) => state.app.currentPrinter);

  const [printerStatus, setPrinterStatus] = useState("");

  useEffect(() => {
    const printerInstance = new Printer({
      target: item.target,
      deviceName: item.deviceName,
    });

    const stopMonitoring = Printer.monitorPrinter(
      printerInstance,
      (status) => {
        if (status.online.statusCode === PrinterConstants.TRUE) {
          setPrinterStatus("online");
        } else {
          setPrinterStatus("offline");
        }
      },
      3000 // Monitoring interval
    );

    return () => stopMonitoring();
  }, [item]);

  const setPrinter = () => {
    if (printerStatus == "online") {
      dispatch(setCurrentPrinter(item));
    } else {
      toast?.showToast({
        type: "error",
        title: null,
        subtitle: t("this_printer_is_offline"),
        duration: 3000,
        noIcon: true,
      });
    }
  };

  const Detail = ({ label, value }) => {
    return (
      <View style={{ flexDirection: "row", width: "80%" }}>
        <Text style={styles.subTextStyle} type={"R16"}>
          {t(label)}
        </Text>
        <Text
          style={[
            styles.subTextStyle,
            { marginLeft: moderateScale(5), color: styles.headerIconColor },
          ]}
          type={"R16"}
        >
          {value}
        </Text>
      </View>
    );
  };

  return (
    <>
      {item && item?.deviceName && (
        <TouchableOpacity
          onPress={setPrinter}
          style={[
            styles.printerItemStyle,
            currentPrinter &&
              currentPrinter?.deviceName == item?.deviceName &&
              currentPrinter?.target == item?.target &&
              styles.selectedPrinterStyle,
          ]}
        >
          {/* <View style={{flexDirection:'row'}}>

        <Text style={styles.subTextStyle} type={'R16'}>{t('device_name')}</Text>
        <Text style={styles.subTextStyle} type={'R16'}>{item?.deviceName}</Text>
      </View> */}
          <View style={{ width: "90%" }}>
            <Detail label={"device_name"} value={item?.deviceName} />
            <Detail label={"ip_address"} value={item?.ipAddress} />
            <Detail label={"mac_address"} value={item?.macAddress} />
            <Detail label={"target"} value={item?.target} />
            <Detail label={"status"} value={printerStatus} />
          </View>
          <View style={{ alignSelf: "center" }}>
            {currentPrinter &&
              currentPrinter?.deviceName == item?.deviceName &&
              currentPrinter?.target == item?.target && (
                <CheckMark
                  width={moderateScale(24)}
                  height={moderateScale(24)}
                  color={theme["color-primary-500"]}
                />
              )}
          </View>
        </TouchableOpacity>
      )}
    </>
  );
};

const RenderHeaderComponent = () => {
  const theme = useTheme();

  const styles = _styles(theme);
  const { t } = useTranslation();

  return <Text type="R16">{t("available_printers")}</Text>;
};

Steps to reproduce

  1. The above code is One of the screen, when user come to this screen and below error shows Image

react-native-esc-pos-printer version

4.4.1,4.4.3,

React Native version

0.78.2

Platforms

iOS

Workflow

React Native

Architecture

Fabric (New Architecture)

Build type

Debug app & dev bundle

Device

None

Device model

ios Simulator and real devices (all)

Acknowledgements

Yes

Mehul175 avatar Jul 16 '25 12:07 Mehul175

@tr3v3r Pls look into this, this is serious issue in library and need to fix ASAP if possible.

Mehul175 avatar Jul 17 '25 09:07 Mehul175

@tr3v3r Pls look into this, this is serious issue in library and need to fix ASAP if possible.

Hello, please create reproducible demo on GitHub and share the link so I can check.

tr3v3r avatar Jul 17 '25 16:07 tr3v3r

@tr3v3r Pls look into this, this is serious issue in library and need to fix ASAP if possible.

Hello, please create reproducible demo on GitHub and share the link so I can check.

https://github.com/Mehul175/React_Native_Printer_Esc_Pos here is the repo i created pls check this.

Mehul175 avatar Jul 22 '25 05:07 Mehul175

@tr3v3r Pls look into this, this is serious issue in library and need to fix ASAP if possible.

Hello, please create reproducible demo on GitHub and share the link so I can check.

https://github.com/Mehul175/React_Native_Printer_Esc_Pos here is the repo i created pls check this.

@tr3v3r Have you checked this, please solve this issue this is crashing app,.

Mehul175 avatar Jul 31 '25 08:07 Mehul175

@tr3v3r Hi bro, I have checked with the expo 54 sdk. still same error when repeating search(start function)

aargon007 avatar Sep 11 '25 07:09 aargon007

@tr3v3r, @Mehul175 I have found the bug. the issue is by default start function search the all device type. there might be device type issue with react native or expo. when i use only deviceType: DiscoveryDeviceType.TYPE_PRINTER this bug didn't appear anymore.

so i call the start function like this

start({
     timeout: 5000,
      filterOption: {
           // deviceModel: DiscoveryDeviceModel.MODEL_ALL, // default
            deviceType: DiscoveryDeviceType.TYPE_PRINTER,
            // portType: DiscoveryFilterOption.PORTTYPE_ALL // can use for filter
      }
});

aargon007 avatar Sep 15 '25 04:09 aargon007

@tr3v3r, @Mehul175 I have found the bug. the issue is by default start function search the all device type. there might be device type issue with react native or expo. when i use only deviceType: DiscoveryDeviceType.TYPE_PRINTER this bug didn't appear anymore.

so i call the start function like this

start({
     timeout: 5000,
      filterOption: {
           // deviceModel: DiscoveryDeviceModel.MODEL_ALL, // default
            deviceType: DiscoveryDeviceType.TYPE_PRINTER,
            // portType: DiscoveryFilterOption.PORTTYPE_ALL // can use for filter
      }
});

@aargon007 can you tell me, exactly where is this?

Mehul175 avatar Sep 15 '25 04:09 Mehul175

@tr3v3r, @Mehul175 I have found the bug. the issue is by default start function search the all device type. there might be device type issue with react native or expo. when i use only deviceType: DiscoveryDeviceType.TYPE_PRINTER this bug didn't appear anymore. so i call the start function like this

start({
     timeout: 5000,
      filterOption: {
           // deviceModel: DiscoveryDeviceModel.MODEL_ALL, // default
            deviceType: DiscoveryDeviceType.TYPE_PRINTER,
            // portType: DiscoveryFilterOption.PORTTYPE_ALL // can use for filter
      }
});

@aargon007 can you tell me, exactly where is this?

replace your start() function with the above start function.

aargon007 avatar Sep 15 '25 05:09 aargon007

@tr3v3r, @Mehul175 I have found the bug. the issue is by default start function search the all device type. there might be device type issue with react native or expo. when i use only deviceType: DiscoveryDeviceType.TYPE_PRINTER this bug didn't appear anymore. so i call the start function like this

start({
     timeout: 5000,
      filterOption: {
           // deviceModel: DiscoveryDeviceModel.MODEL_ALL, // default
            deviceType: DiscoveryDeviceType.TYPE_PRINTER,
            // portType: DiscoveryFilterOption.PORTTYPE_ALL // can use for filter
      }
});

@aargon007 can you tell me, exactly where is this?

replace your start() function with the above start function.

@aargon007 Thanks For this solution

Mehul175 avatar Sep 15 '25 06:09 Mehul175