25648

Linked objects' properties in Realm React-Native ListView return undefined (error: undefined is

I'm trying to access the properties of a linked object through the parent object, but I only get back undefined. <strong>This is code within the renderRow method/prop of ListView (I am using the Realm ListView). On android, haven't tested iOS.</strong> Getting the linked object itself seems to work fine. Heres some (trimmed) code context:

// Schemas being used to create realm (trimmed down to relevant) class Item {}; Item.schema = { name: 'Item', primaryKey: 'id', properties: { id: 'string', name: 'string', department: 'ItemDepartment', } } class ItemDepartment {}; ItemDepartment.schema = { name: 'ItemDepartment', primaryKey: 'id', properties: { id: 'string', name: 'string', parentDepartment: 'ItemDepartment' } } // renderRow method (trimmed but same error thrown) renderRow(item) { return ( <Text>{item.department.name}</Text> ); }

Poking around the realm shows me that both objects appear correctly instantiated with all properties.

I can access each Item string and number properties fine (i.e. item.name). Trying item.department returns a RealmObject, assumedly the one that is linked. item.department.name throws the error "undefined is not an object (evaluating 'item.department.name')"

<strong>This works fine outside of renderRow.</strong>

The long path of poking around has lead me to think the issue lies within this console.log from within renderRow:

renderRow(item) { console.log('item.name: ' + item.name) console.log('item.department: ' + item.department) return ( <Text>{item.name}</Text> ); }

The result:

ReactNativeJS: Running application “undisclosed” with appParams: {"initialProps":{},"rootTag":1}. __DEV__ === true, development-level warning are ON, performance optimizations are OFF ReactNativeJS: item.name: ReactNativeJS: item.department: undefined ReactNativeJS: item.name: defaultGetRowData ReactNativeJS: item.department: undefined ReactNativeJS: item.name: ReactNativeJS: item.department: undefined ReactNativeJS: item.name: defaultGetSectionHeaderData ReactNativeJS: item.department: undefined ReactNativeJS: item.name: undefined ReactNativeJS: item.department: undefined ReactNativeJS: item.name: undefined ReactNativeJS: item.department: undefined ReactNativeJS: item.name: undefined ReactNativeJS: item.department: undefined ReactNativeJS: item.name: undefined ReactNativeJS: item.department: undefined ReactNativeJS: item.name: MockItem1 ReactNativeJS: item.department: [object RealmObject] ReactNativeJS: item.name: MockItem2 ReactNativeJS: item.department: [object RealmObject] ReactNativeJS: item.name: MockItem3 ReactNativeJS: item.department: [object RealmObject]

Interestingly enough the ListView works fine despite renderRow being called several times with nothing and undefined. As soon as I attempt item.department.name though:

Red Screen of death - undefined is not an object

Any feedback and suggestions would be appreciated! Is this a bug with Realm RN ListView or is this working as intended, but my implementation is wrong?

<strong>UPDATE:</strong> Got a dirty work around for now:

getItemDepartmentName(item) { let code = item.code; console.log("item: " + item) console.log("code: " + code) console.log("typeofX: " + typeof code) if (code) { console.log("code True: true") return item.department.name } console.log("code True: false"); return "Undefined" } renderRow(item) { return( <Text>{this.getItemDepartmentName(item)}</Text> ) } // for this to work you must bind this on renderRow in listView: <ListView ... renderRow={this.renderRow.bind(this)} .../>

Basically just checking if the code property of item is truthy or not. Skips the first renderRows. Kept the log lines in for science, shows why this fix works/the bug if you watch in console with

adb logcat ReactNative:V ReactNativeJS:V

Tidied for readability

ReactNativeJS: item: function (row1, row2) {return row1!==row2;} ReactNativeJS: code: undefined ReactNativeJS: typeofX: undefined ReactNativeJS: code True: false ReactNativeJS: item: function defaultGetRowData(dataBlob, sectionID, rowID) { ReactNativeJS: return dataBlob[sectionID][rowID];} ReactNativeJS: code: undefined ReactNativeJS: typeofX: undefined ReactNativeJS: code True: false ReactNativeJS: item: function () {return false;} ReactNativeJS: code: undefined ReactNativeJS: typeofX: undefined ReactNativeJS: code True: false ReactNativeJS: item: function defaultGetSectionHeaderData(dataBlob, sectionID) { ReactNativeJS: return dataBlob[sectionID];} ReactNativeJS: code: undefined ReactNativeJS: typeofX: undefined ReactNativeJS: code True: false ReactNativeJS: item: ReactNativeJS: code: undefined ReactNativeJS: typeofX: undefined ReactNativeJS: code True: false ReactNativeJS: item: ReactNativeJS: code: undefined ReactNativeJS: typeofX: undefined ReactNativeJS: code True: false ReactNativeJS: item: ReactNativeJS: code: undefined ReactNativeJS: typeofX: undefined ReactNativeJS: code True: false ReactNativeJS: item: ReactNativeJS: code: undefined ReactNativeJS: typeofX: undefined ReactNativeJS: code True: false ReactNativeJS: item: [object RealmObject] ReactNativeJS: code: MI1 ReactNativeJS: typeofX: string ReactNativeJS: code True: true ReactNativeJS: item: [object RealmObject] ReactNativeJS: code: MI2 ReactNativeJS: typeofX: string ReactNativeJS: code True: true ReactNativeJS: item: [object RealmObject] ReactNativeJS: code: MI3 ReactNativeJS: typeofX: string ReactNativeJS: code True: true ...

Answer1:

So the following is the constructor that was being used in the project. Don't put your dataSource into your dataSource. Otherwise ListView will call renderRow with properties of the DataSource Object as arguments, leading to all the odd behaviour in the original question.

constructor(props) { super(props); let dataSource = new ListView.DataSource({ rowHasChanged: (row1, row2) => row1 !== row2, }); this.state = { dataSource: dataSource.cloneWithRows(dataSource), // Bad items: realm.objects('Item').sorted('name'), }; this.componentDidMount = this.componentDidMount.bind(this); } componentDidMount() { this.setState({ dataSource: this.state.dataSource.cloneWithRows(this.state.items), }); }

Set state of dataSource with data instead:

... let data = realm.objects('Item').sorted('name') this.state = { dataSource: dataSource.cloneWithRows(data), items: data, }; ...

Turns out my dataSource setup wasn't quite standard!

Answer2:

By looking at your question and logs, it looks like an Item does not always have a department.

Trying item.department returns a RealmObject, <strong>assumedly the one that is linked</strong>. item.department.name throws the error "undefined is not an object (evaluating 'item.department.name')"

So my guess you have some code that isn't checking if item.department is present first before trying to access item.department.name. If item.department is undefined, then the error message you're getting would make sense. Please let me know if that helps, or if I misunderstood something!

Recommend

  • Move struct into a separate file without splitting into a separate module?
  • windowNibName error in Swift / Cocoa?
  • Simplest way to solve a maze without mutability
  • When is “[ $(command) ]” equivalent to “if command; then…”?
  • Create ranking for vector of double
  • opengl: adding higher resolution mipmaps to a texture
  • Jquery - CSS translation with IE
  • Weird session behaviour in codeigniter
  • Getting IIS6 to play nice with WordPress Pretty Permalinks
  • Run script file on remote server
  • Want to save selected (i.e., more than 1) enums as string with NHibernate
  • Javascript/Jquery runs fast in desktop browsers, but slow in mobile/smartphone browsers…should I spl
  • Needing to do .toArray() to get output of mongodb .find() on key name not value
  • CakePHP 2.0.4 - findBy magic methods with conditions
  • How to run “Deployd” on port 80 instead of port 5000 in webserver.
  • Display issues when we change from one jquery mobile page to another in firefox
  • Different response to non-authenticated users and AJAX calls
  • PHP - How to update data to MySQL when click a radio button
  • C# - Serializing and deserializing static member
  • Is possible to count alias result on mysql
  • How to redirect a user to a different server and include HTTP basic authentication credentials?
  • Sending data from AppleScript to FileMaker records
  • Perl system calls when running as another user using sudo
  • Arrow is showed instead of the material design version hamburger icon. Why doesn't syncState in
  • Can a Chrome extension content script make an jQuery AJAX request for an html file that is itself a
  • ActionScript 2 vs ActionScript 3 performance
  • what is the difference between the asp.net mvc application and asp.net web application
  • Upload files with Ajax and Jquery
  • How can I estimate amount of memory left with calling System.gc()?
  • Apache 2.4 - remove | delete | uninstall
  • How to pass list parameters for each object using Spring MVC?
  • Numpy divide by zero. Why?
  • php design question - will a Helper help here?
  • Data Validation Drop Down Box Arrow Disappearing
  • How to include full .NET prerequisite for Wix Burn installer
  • AngularJs get employee from factory
  • Proper way to use connect-multiparty with express.js?
  • IndexOutOfRangeException on multidimensional array despite using GetLength check
  • Authorize attributes not working in MVC 4
  • Is it possible to post an object from jquery to bottle.py?