React-native: React-Native ToastModule Example doesn't override the existing ToastAndroid module.

Created on 2 Oct 2016  路  6Comments  路  Source: facebook/react-native

Hello,

I've done everything for the past week trying to get this to work and I keep getting this error after the compile.

screenshot_1475366073

here is my MainActivity.java:

package com.sharpsix;

import com.facebook.react.ReactActivity;

public class MainActivity extends ReactActivity{

    /**
     * Returns the name of the main component registered from JavaScript.
     * This is used to schedule rendering of the component.
     */
    @Override
    protected String getMainComponentName() {
        return "SharpSix";
    }
}


here is my MainApplication.java:

com.sharpsix;

import android.app.Application;
import android.util.Log;

import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.shell.MainReactPackage;
import java.util.Arrays;
import java.util.List;

     public class MainApplication extends Application implements ReactApplication {

     private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
     @Override
     protected boolean getUseDeveloperSupport() {
      return BuildConfig.DEBUG;
     }

    @Override
     protected List<ReactPackage> getPackages() {
      return Arrays.<ReactPackage>asList(
          new MainReactPackage(),
          new AnExampleReactPackage()
          );
       }
  };

       @Override
       public ReactNativeHost getReactNativeHost() {
       return mReactNativeHost;
  }
}


here is my AnExampleReactPackage.java:

  package com.sharpsix;

     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;

public class AnExampleReactPackage implements ReactPackage {

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

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

      @Override
      public List<NativeModule> createNativeModules(
                                  ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();

        modules.add(new ToastModule(reactContext));

        return modules;
    }    
}


Here is my ToastModule.java:

package com.sharpsix;

import android.widget.Toast;

import com.facebook.react.bridge.NativeModule;
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 java.util.Map;
import java.util.HashMap;

public class ToastModule extends ReactContextBaseJavaModule {

    private static final String DURATION_SHORT_KEY = "SHORT";
    private static final String DURATION_LONG_KEY = "LONG";

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


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

    @Override
      public Map<String, Object> getConstants() {
        final Map<String, Object> constants = new HashMap<>();
        constants.put(DURATION_SHORT_KEY, Toast.LENGTH_SHORT);
        constants.put(DURATION_LONG_KEY, Toast.LENGTH_LONG);
        return constants;
      }

    @ReactMethod
      public void show(String message, int duration) {
        Toast.makeText(getReactApplicationContext(), message, duration).show();
      } 


}

I've tried this multiple times with the latest build of RN and I've haven't had any luck. Please help...

Locked

Most helpful comment

For anyone else who falls into this; Renaming:

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

To be anything else, such as ToastAndroidTutorial:

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

And ensuring that you also update the wrapped JS file to reference this new name:

import { NativeModules } from 'react-native';

// Before: `module.exports = NativeModules.ToastAndroid;`
export default NativeModules.ToastAndroidTutorial;

All 6 comments

Don't use the same module name ToastAndroid

Why import Toaster from the index.android.js? index.android.js should be the APP entry point.

figured it out... I had to just call the ToastAndroid module without changing any of the android .java files.

index.android.js:

import React, {
    Component
} from 'react';

import {
    AppRegistry
} from 'react-native';
import { NativeModules } from 'react-native';

module.exports = NativeModules.ToastAndroid;

import App from './App';



AppRegistry.registerComponent('SharpSix', () => App);

App.js:

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 * @flow
 */
// import { NativeModules } from 'react-native';
var ReactNative = require('react-native')
// module.exports = ReactNative.NativeModules.ContactsWrapper
import React, { Component } from 'react';
import {
  StyleSheet,
  Text,
  View,
  Image,
  TouchableHighlight
} from 'react-native';

var ToastAndroid = require('NativeModules').ToastAndroid;

export default class App extends Component {
  constructor(props) {
        super(props);

    }
  _onPressSharpButton() {
    console.log("You tapped the sharpBtn");
    ToastAndroid.show('Awesome', ToastAndroid.LONG);
  }
  _onPressInfoButton() {
    console.log("You tapped the infoBtn")
  }
  _onPressAddButton1() {
    console.log("You tapped the addBtn1")
    // ContactsWrapper.getContact()
    //     .then((contact) => {
    //         // Replace this code
    //         console.log(contact);
    //     })
    //     .catch((error) => {
    //         console.log("ERROR CODE: ", error.code);
    //         console.log("ERROR MESSAGE: ", error.message);
    //     });
  }
  _onPressAddButton2() {...etc

After making these changes the Toast appeared... I understand the tutorial from the React-Native docs they could've done a better job of explaining that you need to create your own Node Module if it's not an AndroidReact module. Either way I hope this helps someone out there.

I think the confusion was that the documentation did not mention ToastAndroid was a real native module implemented as part of React Native. It serves a purpose as a tutorial for Java native modules, but it also has a production use case.

You can close the issue @dooleydragon if you have no further comments.

For anyone else who falls into this; Renaming:

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

To be anything else, such as ToastAndroidTutorial:

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

And ensuring that you also update the wrapped JS file to reference this new name:

import { NativeModules } from 'react-native';

// Before: `module.exports = NativeModules.ToastAndroid;`
export default NativeModules.ToastAndroidTutorial;

I've run into this same issue and you indirectly solved it. The primary issue for me was that, as described in the tutorial, I was adding the package within getPackages() in MainActivity.java, whereas its actually needed in MainApplication.java, as shown in the example above.

I'm fairly certain anyone following the tutorial in Facebook's docs is just writing a bunch of code and then using the stock ToastAndroid module that comes as part of React Native (adding and removing packages within MainActivity does nothing, as far as I can tell. Maybe MainApplication overwrites the packages?

Was this page helpful?
0 / 5 - 0 ratings