2

I am trying to run the most basic React Native example where i am tring to change a text passed to a custom java module :

My index.android.js file :

var React = require('react-native');
var Image = React.Image;
var Button= require('react-native-button');
var NativeModules = React.NativeModules;
var TouchableNativeFeedback = React.TouchableNativeFeedback;

var Directory2 = React.createClass({
render: function() {
  var layout =
      <React.View style = { styles.parent } >
          <React.Text>
              Enter Host :
          </React.Text>

          <React.TextInput
              onChangeText={(e) => this.setState({input: e})}
              text = { this.state.input }
              onSubmitEditing = { this.showMeaning }
          />

          <Image source={ this.state.setImg } style={styles.img} />

          <Button
            style={styles.button}
            onPress={this._handlePress}>
            Test
          </Button>
      </React.View>
  ;
  return layout;
},
getInitialState: function() {
return {
    input : '',
    setImg : require('image!red'),
    text: 'Goodbye World.'
};
},
showMeaning: function() {
  // Use the ternary operator to check if the word 
  // exists in the dictionary.
  var meaning = "you entered some text";

  // Update the state
  this.setState({
       output: meaning 
  });
},
_handlePress: function() {
  this.setState({
      setImg : require('image!green')
 });

  require('NativeModules').PingModule.processString( this.state.text, (text) => { alert(text); });
 },
 });

var styles = React.StyleSheet.create({

// For the container View
parent: {
    padding: 16
},

img : {
  alignSelf : 'flex-start'
},

button: {
  textAlign : 'center',
  backgroundColor : '#FF0000',
  width : 100,
  alignSelf : 'flex-end'
},

buttonText: {
  fontWeight: 'bold'
},
});

React.AppRegistry.registerComponent('Directory2', function() {
   return Directory2;
});

My MainActivity.java file :

package com.directory2;

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;

import com.facebook.react.LifecycleState;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
import com.facebook.react.shell.MainReactPackage;
import com.facebook.soloader.SoLoader;

// Add extra packages here
import com.directory2.CustomPackages;

public class MainActivity extends Activity implements DefaultHardwareBackBtnHandler {

private ReactInstanceManager mReactInstanceManager;
private ReactRootView mReactRootView;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mReactRootView = new ReactRootView(this);

    mReactInstanceManager = ReactInstanceManager.builder()
            .setApplication(getApplication())
            .setBundleAssetName("index.android.bundle")
            .setJSMainModuleName("index.android")
            .addPackage(new MainReactPackage()) // Add packages here!
            .addPackage(new CustomPackages()) // <-- and here
            .setUseDeveloperSupport(BuildConfig.DEBUG)
            .setInitialLifecycleState(LifecycleState.RESUMED)
            .build();

    mReactRootView.startReactApplication(mReactInstanceManager, "Directory2", null);

    setContentView(mReactRootView);
}

@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
    if (keyCode == KeyEvent.KEYCODE_MENU && mReactInstanceManager != null) {
        mReactInstanceManager.showDevOptionsDialog();
        return true;
    }
    return super.onKeyUp(keyCode, event);
}

@Override
public void onBackPressed() {
  if (mReactInstanceManager != null) {
    mReactInstanceManager.onBackPressed();
  } else {
    super.onBackPressed();
  }
}

@Override
public void invokeDefaultOnBackPressed() {
  super.onBackPressed();
}

@Override
protected void onPause() {
    super.onPause();

    if (mReactInstanceManager != null) {
        mReactInstanceManager.onPause();
    }
}

@Override
protected void onResume() {
    super.onResume();

    if (mReactInstanceManager != null) {
        mReactInstanceManager.onResume(this, this);
    }
}
}

My React package file :

package com.directory2;


import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


import java.util.Arrays;
import java.util.List;

public class CustomPackages implements ReactPackage {

@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
  List<NativeModule> modules = new ArrayList<>();
  modules.add(new PingModule(reactContext));
  return modules;
}

public List<Class<? extends JavaScriptModule>> createJSModules() {
  return Collections.emptyList();
}

public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
  return Collections.emptyList();
}

}

And my Module file :

package com.directory2;

import com.facebook.react.bridge.ReactContextBaseJavaModule;

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.bridge.Callback;
import com.facebook.react.bridge.NativeModule;

public class PingModule extends ReactContextBaseJavaModule {

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

// Available as NativeModules.MyCustomModule.processString
@ReactMethod
public void processString(String input, Callback callback) {
    callback.invoke(input.replace("Goodbye", "Hello"));
}

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

The project builds but when i click on "Test" button

require('NativeModules').PingModule.processString( this.state.text, (text) => { alert(text); });

Above line throws error

undefined is not an object (evaluating 'require('NativeMobules').PingModule.processString')

2
  • 2
    Change "HelloWorld" in getName() to your export name, in this case "PingModule" Commented Jan 22, 2016 at 9:41
  • Thank You @kar this was the issue. I changed "HelloWorld" to "PingModule" and it worked. Thank you :) Commented Jan 24, 2016 at 21:52

1 Answer 1

3

Add this code to the end of PingModule -

export default PingModule;

You gotta export modules to make them usable.

Sign up to request clarification or add additional context in comments.

4 Comments

You can call directly with NativeModules.PingModule.processString(), export not needed.
Interesting..., can you please link to any page where I can read more about this? Thanks.
"To make it simpler to access your new functionality from JavaScript, it is common to wrap the native module in a JavaScript module. This is not necessary but saves the consumers of your library the need to pull it off of NativeModules each time. This JavaScript file also becomes a good location for you to add any JavaScript side functionality." -- facebook.github.io/react-native/docs/…
Thank you guys for your help. @kar has answered the question.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.