Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"'undefined' is not an object" from Native Module in React Native

I am getting the following error when trying to invoke a method in a Native Module:

'undefined' is not an object (evaluating 'ScaleController. updateScaleFromJSON')

My native module Objective-C files -

RCTScaleController.h:

#ifndef RCTScaleController_h
#define RCTScaleController_h

#import "RCTBridgeModule.h"

@interface RCTScaleController : NSObject <RCTBridgeModule>
@end

#endif /* RCTScaleController_h */

RCTScaleController.mm:

#import "RCTScaleController.h"
#import "ScaleControllerObjC.h"
#import "RCTLog.h"

@implementation RCTScaleController

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(updateScaleFromJSON:(NSString *)jsonString)
{
    RCTLogInfo(@"About to send json: %@", jsonString);
    ScaleControllerObjC *scaleController = [[ScaleControllerObjC alloc] init];
    [scaleController updateScaleFromJSON:jsonString];
}

Here it is being required in my JS file:

var ScaleController = require('react-native').NativeModules.RCTScaleController;

And here it is being invoked causing the error:

ScaleController.updateScaleFromJSON (JSON.stringify (scale));

I've followed the examples I've seen and not sure whats wrong here..

like image 245
Adamski Avatar asked Jan 28 '16 03:01

Adamski


Video Answer


2 Answers

Generally if a module is prefixed by RCT, in NativeModules it will only be the substring after it, so you don't have to rename your entire module, just call it differently from NativeModules.

Example:

So e.g. in the case of Android if your getName() function does return a name like "RCTMyName":

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

then back in Javascript, you have to call it without RCT, i.e. just MyName:

import { NativeModules } from 'react-native';
export default NativeModules.MyName;
like image 157
Andru Avatar answered Sep 20 '22 13:09

Andru


I ran into this issue for a long time adding React Native to an existing android app. My problem was that, integrating React Native, the guide on creating native modules did not mention that the package needs to be declared in the ReactInstanceManager instance in this scenario, not in the main Application file. For Android, the instance declaration would look like so (probably analogous for iOS):

ReactInstanceManager.builder()
            .setApplication(application)
            .setBundleAssetName("index.android.bundle")
            .setJSMainModulePath("index")
            .addPackage(new MainReactPackage())
            .addPackage(new MyTestPackage())
            .setUseDeveloperSupport(BuildConfig.DEBUG)
            .setInitialLifecycleState(LifecycleState.RESUMED)
            .build();

This can be hard to spot, especially when using Dependency injection :).

I created a request for a doc update here.

like image 32
Moritz Avatar answered Sep 21 '22 13:09

Moritz