Convert java object(string) to react element to print?

Error I’m getting : “t.render(): A valid React element (or null) must be returned. You may have returned undefined; an array or some other invalid object.”

I think I am getting this error because my object is a java object and is undefined in react.

This is a linked question: How do you print/output returned Raw text from a React Module function(Get Call Log)?

Here is my logcat:

--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
I/ReactNativeJS(20462): Running application "WorkingApp" with appParams: {"rootTag":1}. __DEV__ === false, development-level warning are OFF, performance optimizations are ON
E/ReactNativeJS(20462): t.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
I/ReactNativeJS(20716): Running application "WorkingApp" with appParams: {"rootTag":1}. __DEV__ === false, development-level warning are OFF, performance optimizations are ON
E/ReactNativeJS(20716): t.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
I/ReactNativeJS(21045): Running application "WorkingApp" with appParams: {"rootTag":1}. __DEV__ === false, development-level warning are OFF, performance optimizations are ON
E/ReactNativeJS(21045): t.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
I/ReactNativeJS(21475): Running application "WorkingApp" with appParams: {"rootTag":1}. __DEV__ === false, development-level warning are OFF, performance optimizations are ON
E/ReactNativeJS(21475): t.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.
I/ReactNativeJS(21679): Running application "WorkingApp" with appParams: {"rootTag":1}. __DEV__ === false, development-level warning are OFF, performance optimizations are ON
E/ReactNativeJS(21679): Can't find variable: Console
I/ReactNativeJS(21814): Running application "WorkingApp" with appParams: {"rootTag":1}. __DEV__ === false, development-level warning are OFF, performance optimizations are ON
I/ReactNativeJS(21814): undefined
E/ReactNativeJS(21814): t.render(): A valid React element (or null) must be returned. You may have returned undefined, an array or some other invalid object.

Here is my java class:

public class CallLogModule extends ReactContextBaseJavaModule implements LoaderManager.LoaderCallbacks<Cursor>{
    public static final String REACT_CLASS = "CallLogAndroid";
    private static final String E_LAYOUT_ERROR = "E_LAYOUT_ERROR";
    ReactApplicationContext reactContext;
    private static HashMap<String, String> rowDataCall;
    private static final String TAG = "CallLog";
    private static final int URL_LOADER = 1;

    private static TextView callLogsTextView;

    // @Override
    // public void onCreate(Bundle savedInstanceState) {
    //     super.onCreate(savedInstanceState);
    //     Log.d(TAG, "onCreate()");

    //     setContentView(R.layout.main);
    //     initialize();
    // }

    /**Constructor */
    public CallLogModule(ReactApplicationContext reactContext) {
        super(reactContext);
        this.reactContext= reactContext;
        //(Activity)reactContext.setContentView(R.layout.module_layout);
    }


    /**Loads all calls */
    @Override
    @ReactMethod
    public Loader onCreateLoader(int loaderID, Bundle args) {

    Log.d(TAG, "onCreateLoader() >> loaderID : " + loaderID);

    switch (loaderID) {
        case URL_LOADER:
        // Returns a new CursorLoader
        return new CursorLoader(
        reactContext,   // Parent activity context
        CallLog.Calls.CONTENT_URI,        // Table to query
        null,     // Projection to return
        null,            // No selection clause
        null,            // No selection arguments
        null             // Default sort order
        );

        default:
        return null;
        }
    }

    /**On completing load, return/output formatted string*/
    @Override
    @ReactMethod
    public void onLoadFinished(Loader loader, Cursor managedCursor) {
        Log.d(TAG, "onLoadFinished()");

        StringBuilder sb = new StringBuilder();

        int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
        int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
        int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
        int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);

        sb.append("<h4>Call Log Details <h4>");
        sb.append("/n");
        sb.append("/n");

        sb.append("<table>");

        while (managedCursor.moveToNext()) {
            String phNumber = managedCursor.getString(number);
            String callType = managedCursor.getString(type);
            String callDate = managedCursor.getString(date);
            //Date callDayTime = new Date(Long.valueOf(callDate));
            Date callDayTime= null;
            if( (!callDate.trim().equals("") ) && (callDate != null)) {    
                callDayTime = new Date(Long.valueOf(callDate));  //if value of long is null
            }
            String callDuration = managedCursor.getString(duration);
            String dir = null;

            int callTypeCode = Integer.parseInt(callType);
            switch (callTypeCode) {
                case CallLog.Calls.OUTGOING_TYPE:
                    dir = "Outgoing";
                    break;

                case CallLog.Calls.INCOMING_TYPE:
                    dir = "Incoming";
                    break;

                case CallLog.Calls.MISSED_TYPE:
                    dir = "Missed";
                    break;
            }

            sb.append("<tr>")
                    .append("<td>Phone Number: </td>")
                    .append("<td><strong>")
                    .append(phNumber)
                    .append("</strong></td>");
            sb.append("</tr>");
            sb.append("<br/>");
            sb.append("<tr>")
                    .append("<td>Call Type:</td>")
                    .append("<td><strong>")
                    .append(dir)
                    .append("</strong></td>");
            sb.append("</tr>");
            sb.append("<br/>");
            sb.append("<tr>")
                    .append("<td>Date & Time:</td>")
                    .append("<td><strong>")
                    .append(callDayTime)
                    .append("</strong></td>");
            sb.append("</tr>");
            sb.append("<br/>");
            sb.append("<tr>")
                    .append("<td>Call Duration (Seconds):</td>")
                    .append("<td><strong>")
                    .append(callDuration)
                    .append("</strong></td>");
            sb.append("</tr>");
            sb.append("<br/>");
            sb.append("<br/>");
        }
        sb.append("</table>");

        managedCursor.close();

        callLogsTextView.setText(Html.fromHtml(sb.toString()),TextView.BufferType.SPANNABLE);
    }

    @Override
    @ReactMethod
    public void onLoaderReset(Loader<Cursor> loader) {
        Log.d(TAG, "onLoaderReset()");
        // do nothing
    }

    /**Method to obtain name of the class */
    @Override
    public String getName() {
        return REACT_CLASS;
    }


    /**Method to get entire call log */
    // @ReactMethod
    // public void getCallLog(String phone,int duration) {
    //     //Checking if permission was denied
    //     if (ActivityCompat.checkSelfPermission(getCurrentActivity(), Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED){
    //         ActivityCompat.requestPermissions(getCurrentActivity(), new String[]{Manifest.permission.READ_CALL_LOG}, 101);
    //     }

    //     //uses a cursor to get all calls
    //    else{
    //         Uri allCalls = Uri.parse("content://call_log/calls");
    //         Cursor c = managedQuery(allCalls, null, null, null, null);

    //         //separates calls according to number; name; duration and Call type
    //         String num= c.getString(c.getColumnIndex(CallLog.Calls.NUMBER));// for  number
    //         String name= c.getString(c.getColumnIndex(CallLog.Calls.CACHED_NAME));// for name
    //         String duration = c.getString(c.getColumnIndex(CallLog.Calls.DURATION));// for duration
    //         int type = Integer.parseInt(c.getString(c.getColumnIndex(CallLog.Calls.TYPE)));// for call type, Incoming or out-going.

    //         //Print calls in a certain format

    //     }
    // }

    /**Method to get full list of call logs */
    @ReactMethod

    //Promise promise
    private void getCallDetails() throws UnsupportedEncodingException, JSONException{

            //try{


            StringBuffer sb = new StringBuffer();
            Uri contacts = CallLog.Calls.CONTENT_URI;
            Cursor managedCursor = (reactContext.getCurrentActivity()).getContentResolver().query(contacts, null, null, null, null);
            int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
            int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
            int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
            int duration = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
            //sb.append("Call Details :");

            sb.append("<h1>Call Log Details </h1>");  //tried to print out with react syntax contrary to code commented below
            sb.append("/n");
            sb.append("/n");

            sb.append("<table>");

            while (managedCursor.moveToNext()) {

                rowDataCall = new HashMap<String, String>();

                String phNumber = managedCursor.getString(number);
                String callType = managedCursor.getString(type);
                String callDate = managedCursor.getString(date);
                String callDayTime = new Date(Long.valueOf(callDate)).toString();
                // long timestamp = convertDateToTimestamp(callDayTime);
                String callDuration = managedCursor.getString(duration);
                String dir = null;
                int dircode = Integer.parseInt(callType);
                switch (dircode) {
                case CallLog.Calls.OUTGOING_TYPE:
                    dir = "OUTGOING";
                    break;

                case CallLog.Calls.INCOMING_TYPE:
                    dir = "INCOMING";
                    break;

                case CallLog.Calls.MISSED_TYPE:
                    dir = "MISSED";
                    break;
                }
                // sb.append("/nPhone Number:--- " + phNumber + " /nCall Type:--- " + dir + " /nCall Date:--- " + callDayTime + " /nCall duration in sec :--- " + callDuration);
                // sb.append("/n----------------------------------");

                sb.append("<tr>")
                        .append("<td>Phone Number: </td>")
                        .append("<td><strong>")
                        .append(phNumber)
                        .append("</strong></td>");
                sb.append("</tr>");
                sb.append("<br/>");
                sb.append("<tr>")
                        .append("<td>Call Type:</td>")
                        .append("<td><strong>")
                        .append(dir)
                        .append("</strong></td>");
                sb.append("</tr>");
                sb.append("<br/>");
                sb.append("<tr>")
                        .append("<td>Date & Time:</td>")
                        .append("<td><strong>")
                        .append(callDayTime)
                        .append("</strong></td>");
                sb.append("</tr>");
                sb.append("<br/>");
                sb.append("<tr>")
                        .append("<td>Call Duration (Seconds):</td>")
                        .append("<td><strong>")
                        .append(callDuration)
                        .append("</strong></td>");
                sb.append("</tr>");
                sb.append("<br/>");
                sb.append("<br/>");
            }
            sb.append("</table>");

            managedCursor.close();
            String clLog=sb.toString();

            //WebView webview = new WebView(reactContext.getCurrentActivity());
            //String html_str = URLEncoder.encode(sb.toString(), "UTF-8");
            //JSONObject obj = new JSONObject();
            //obj.put("Call log", clLog);

            //JSON.stringify(clLog);
            //promise.resolve(html_str);
            //}

           // catch (IllegalViewOperationException e) { promise.reject(E_LAYOUT_ERROR, e); }

            System.out.println(sb.toString());
            // callLogsTextView.setText(Html.fromHtml(sb.toString()));

            // WebView webview = new WebView(reactContext.getCurrentActivity());
            // webview.loadData(sb.toString(), "text/html", "utf-8");

            //Toast.makeText(reactContext, sb.toString(), Toast.LENGTH_LONG).show();


//            LayoutInflater inflater = reactContext.getCurrentActivity().getLayoutInflater();
//            View layout = inflater.inflate(R.layout.module_layout,
//                    (ViewGroup) reactContext.getCurrentActivity().findViewById(R.id.custom_toast_container));
//
//            ImageView image = (ImageView) layout.findViewById(R.id.image);
//            image.setImageResource(R.drawable.android);
//            TextView text = (TextView) layout.findViewById(R.id.text);
//            text.setText(sb.toString());
//
//            Toast toast = new Toast(reactContext.getCurrentActivity());
//            toast.setGravity(Gravity.CENTER_VERTICAL, 0, 0);
//            toast.setDuration(Toast.LENGTH_LONG);
//            toast.setView(layout);
//            toast.show();
    }
}

Here is my React class:

import React, { Component } from 'react';
import { NativeModules, AppRegistry, SectionList, StyleSheet, Text, View, WebView } from 'react-native';
import { StackNavigator, } from 'react-navigation';
import CallLogAndroid from './RctActivity';


export default class SectionListBasics extends Component {
  static navigationOptions = { title: 'Your Call Logs', };
   CallLog = () =>{
      const Cllog= CallLogAndroid.getCallDetails();
      console.log(Cllog+"");
      return Cllog+"";
  };

  // Can't use async await, npm < 5
  // async function getCallLog() {              
  //     try {
  //       var CallDetails = await CallLogAndroid.getCallDetails(100, 100);
  //       console.log(CallDetails);
  //       return CallDetails;
  //     } 
  //     catch (e) {
  //       console.error(e);
  //     }
  // }
  // componentWillMount() {
  //     const log = CallLogAndroid.getCallDetails().then(function(value) {
  //       console.log(value); // "Success"
  //     }, function(value) {
  //       // not called
  //     });
  // }


  render() {

    // const divStyle = {
    //   WebkitTransition: 'all', // note the capital 'W' here
    //   msTransition: 'all' // 'ms' is the only lowercase vendor prefix
    // };
     const obj1= CallLogAndroid.getCallDetails();


    // var thenProm = resolvedProm.then(function(value){
    //   console.log("this gets called after the end of the main stack. the value received and returned is: " + value);
    //   return value;
    // });

    // console.log(this.log+"");

    //getCallLog();
    return (
      console.log(JSON.stringify(obj1))

      // <View style={styles.container}>
      //    <SectionList
      //     sections={[
      //       {title: 'Today', data: [ 'pete'] },
      //       {/* <WebView source={{html: CallLogAndroid.getCallDetails()}} /> */},
      //       {title: 'Yesterday', data: ['Jackson']},
      //       {title: 'Date: 1', data: ['shivaan']},
      //       {title: 'Date: 2', data: ['Suraksha']},
      //       {title: 'Date: 3', data: ['Asha']},
      //       {title: 'Date: 4', data: ['Mum']},
      //       {title: 'Date: 5', data: ['Dad']},
      //     ]}
      //     renderItem={({item}) => <Text style={styles.item}>{item}</Text>}
      //     renderSectionHeader={({section}) => <Text style={styles.sectionHeader}>{section.title}</Text>}
      //   /> 
      //   {/* <Text>
      //   console.log(CallLogAndroid.getCallDetails().toString());

      //   </Text> */}
      // </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
   flex: 1,
   paddingTop: 22
  },
  sectionHeader: {
    paddingTop: 2,
    paddingLeft: 10,
    paddingRight: 10,
    paddingBottom: 2,
    fontSize: 20,
    fontWeight: 'bold',
    backgroundColor: 'rgba(247,247,247,1.0)',
  },
  item: {
    padding: 10,
    fontSize: 18,
    height: 44,
  },
})