Search code examples
typescriptreact-nativeeventslistenerreact-native-modules

Sending Events to JavaScript from Your Native Module in React Native?


I'm trying to pass an event from my module to react native. I followed these steps Here but it didn't work as expected. I don't receive errors but it simply doesn't work.

Here is my code in Android Studio inside my module:

package com.coinboxcollector;

import android.util.Log;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.module.annotations.ReactModule;
import com.facebook.react.modules.core.DeviceEventManagerModule;

@ReactModule(name = CoinboxCollectorModule.NAME)
public class CoinboxCollectorModule extends ReactContextBaseJavaModule {
  public static final String NAME = "CoinboxCollector";

  public CoinboxCollectorModule(ReactApplicationContext reactContext) {
    super(reactContext);
  }

  @NonNull
  @Override
  public String getName() {
    return "CoinBoxCollector";
  }

  private static String port="/dev/tty.usbserial-fa14";
  public MyCCT cct;
  public CoinObserver coinObserver =  new CoinObserver() {
    private ReactContext reactContext;
    @Override
    public void update(MyCCT cct, float coin) {
      Log.d("Coin", Float.toString(coin));
      try {
        this.reactContext
          .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
          .emit("onReceivedCoin", coin);
      }catch (Exception ex){
      }
    }
  };

  @ReactMethod
  public void initialize(Promise promise)
  {
    try{
      Log.d("stato", "inizializzazione ");
      if(cct == null){
        cct = new MyCCT(port, this.getReactApplicationContext());
      }
      cct.addCoinObserver(coinObserver);
      cct.start();
      promise.resolve(true);
    }catch (Exception err){
      promise.resolve(false);

    }
  }

  @ReactMethod
  public void stop(Promise promise)
  {
    try{
      cct.stop();
      cct = null;
      promise.resolve(true);
    }catch (Exception err){
      promise.resolve(false);
    }
  }

  @ReactMethod
  public void addListener(String eventName) {

  }

  @ReactMethod
  public void removeListeners(Integer count) {

  }

  @ReactMethod
  public void multiply(double a, double b, Promise promise) {
    promise.resolve(a * b);
  }
}

My code in react native:

import {useNavigation} from '@react-navigation/native';
import React, {useEffect, useRef, useState} from 'react';
import {
  Alert,
  DeviceEventEmitter,
  NativeEventEmitter,
  NativeModules,
  Pressable,
  StyleSheet,
  Text,
  View,
} from 'react-native';
const {CoinBoxCollector} = NativeModules;

export default function HomeScreen() {
  const [off, setOff] = useState(true);

  const navigation = useNavigation();

  let coinInserted = 0;
  const coinValueStartExperience = 2;

  async function onCoinDetected(coin: any) {
    Alert.alert('ricevuti soldi', coin);
    console.log('ricevuti soldi');
  }

  const pressInit = async () => {
    return await CoinBoxCollector.initialize();
  };

  const pressStop = async () => {
    return await CoinBoxCollector.stop();
  };

  useEffect(() => {
    const eventEmitter = new NativeEventEmitter(NativeModules.CoinBoxCollector);
    const eventListener = eventEmitter.addListener(
      'onReceivedCoin',
      onCoinDetected,
    );
    return eventListener.remove();
  }, []);

  return (
    <View style={styles.container}>
      <Pressable style={styles.btn} onPress={pressInit}>
        <Text style={styles.btnText}>Initialize</Text>
      </Pressable>
      <Pressable style={styles.btn} onPress={pressStop}>
        <Text style={styles.btnText}>Stop it</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignContent: 'center',
  },
  btn: {
    marginTop: 30,
    backgroundColor: '#841584',
    width: '5%',
    height: 30,
    marginLeft: '48%',
  },
  btnText: {
    color: 'white',
    textAlign: 'center',
  },
});

In general I'm trying to do all of that to take the coin from the event (coin which I insert in the coinbox) and put it in a future condition. Thank you all in advance for the help


Solution

  • You followed the docs to events for "Native Modules".

    The correctly docs is to events for "Native Components".

    https://reactnative.dev/docs/native-components-android#events