Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot index a property using TypeScript #6607

Open
thegreatzeus opened this issue Apr 11, 2024 · 8 comments
Open

Cannot index a property using TypeScript #6607

thegreatzeus opened this issue Apr 11, 2024 · 8 comments
Labels

Comments

@thegreatzeus
Copy link

How frequently does the bug occur?

Always

Description

I'm trying to index a string property on a Realm model using TypeScript.

I'm using Realm's React Native SDK with Realm's Expo example app.

Using the same example from Realm's docs:

class Book extends Realm.Object<Book> {
  name!: string;
  price?: number;

  static schema: ObjectSchema = {
    name: 'Book',
    properties: {
      name: {type: 'string', indexed: true},
      price: 'int?',
    },
  };
}

Results in the following error:

Classes extending Realm.Object cannot define their own `schema` static, 
all properties must be defined using TypeScript syntax

Stacktrace & log output

at visitRealmClass (/AtlasDeviceSdkApp/node_modules/@realm/babel-plugin/dist/plugin/index.js:323:15)
    at PluginPass.ClassDeclaration (/AtlasDeviceSdkApp/node_modules/@realm/babel-plugin/dist/plugin/index.js:375:25)
    at newFn (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/visitors.js:160:14)
    at NodePath._call (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/path/context.js:46:20)
    at NodePath.call (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/path/context.js:36:17)
    at NodePath.visit (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/path/context.js:82:31)
    at TraversalContext.visitQueue (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/context.js:89:16)
    at TraversalContext.visitSingle (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/context.js:65:19)
    at TraversalContext.visit (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/context.js:112:19)
    at traverseNode (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/traverse-node.js:22:17)
    at NodePath.visit (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/path/context.js:88:52)
    at TraversalContext.visitQueue (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/context.js:89:16)
    at TraversalContext.visitMultiple (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/context.js:61:17)
    at TraversalContext.visit (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/context.js:110:19)
    at traverseNode (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/traverse-node.js:22:17)
    at NodePath.visit (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/path/context.js:88:52)
    at TraversalContext.visitQueue (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/context.js:89:16)
    at TraversalContext.visitSingle (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/context.js:65:19)
    at TraversalContext.visit (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/context.js:112:19)
    at traverseNode (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/traverse-node.js:22:17)
    at traverse (/AtlasDeviceSdkApp/node_modules/@babel/traverse/lib/index.js:52:34)
    at transformFile (/AtlasDeviceSdkApp/node_modules/@babel/core/lib/transformation/index.js:82:31)
    at transformFile.next (<anonymous>)
    at run (/AtlasDeviceSdkApp/node_modules/@babel/core/lib/transformation/index.js:24:12)
    at run.next (<anonymous>)
    at /AtlasDeviceSdkApp/node_modules/@babel/core/lib/transform-ast.js:23:33
    at Generator.next (<anonymous>)
    at evaluateSync (/AtlasDeviceSdkApp/node_modules/gensync/index.js:251:28)
    at sync (/AtlasDeviceSdkApp/node_modules/gensync/index.js:89:14)
    at stopHiding - secret - don't use this - v1 (/AtlasDeviceSdkApp/node_modules/@babel/core/lib/errors/rewrite-stack-trace.js:47:12)
    at transformFromAstSync (/AtlasDeviceSdkApp/node_modules/@babel/core/lib/transform-ast.js:43:83)
    at Object.transform (/AtlasDeviceSdkApp/node_modules/metro-react-native-babel-transformer/src/index.js:201:20)
    at transformJSWithBabel (/AtlasDeviceSdkApp/node_modules/metro-transform-worker/src/index.js:330:45)
    at Object.transform (/AtlasDeviceSdkApp/node_modules/metro-transform-worker/src/index.js:461:18)
    at transformFile (/AtlasDeviceSdkApp/node_modules/metro/src/DeltaBundler/Worker.flow.js:73:36)
    at Object.transform (/AtlasDeviceSdkApp/node_modules/metro/src/DeltaBundler/Worker.flow.js:48:10)
    at execFunction (/AtlasDeviceSdkApp/node_modules/jest-worker/build/workers/processChild.js:137:17)
    at execHelper (/AtlasDeviceSdkApp/node_modules/jest-worker/build/workers/processChild.js:116:5)
    at execMethod (/AtlasDeviceSdkApp/node_modules/jest-worker/build/workers/processChild.js:120:5)
    at process.messageListener (/AtlasDeviceSdkApp/node_modules/jest-worker/build/workers/processChild.js:38:7)
    at process.emit (node:events:517:28)
    at emit (node:internal/child_process:944:14)


### Can you reproduce the bug?

Always

### Reproduction Steps

Use the Expo template app and try to define a new model using TypeScript such as [the example](https://www.mongodb.com/docs/realm/sdk/react-native/model-data/define-a-realm-object-model/#index-a-property):

```ts
class Book extends Realm.Object<Book> {
  name!: string;
  price?: number;

  static schema: ObjectSchema = {
    name: 'Book',
    properties: {
      name: {type: 'string', indexed: true},
      price: 'int?',
    },
  };
}

Version

"realm": "12.0.0", "@realm/react": "^0.6.0",

What services are you using?

Local Database only

Are you using encryption?

No

Platform OS and version(s)

Android 14

Build environment

Node v18.19.1

package.json contents:

{
  "name": "atlasdevicesdkapp",
  "version": "1.0.0",
  "scripts": {
    "start": "expo start --dev-client",
    "android": "expo run:android",
    "ios": "expo run:ios"
  },
  "dependencies": {
    "@realm/react": "^0.6.0",
    "expo": "^49.0.8",
    "expo-dev-client": "~2.4.8",
    "expo-splash-screen": "~0.20.5",
    "expo-status-bar": "~1.6.0",
    "react": "18.2.0",
    "react-native": "0.72.4",
    "react-native-get-random-values": "~1.9.0",
    "realm": "12.0.0"
  },
  "devDependencies": {
    "@babel/core": "^7.22.5",
    "@babel/plugin-proposal-decorators": "^7.22.5",
    "@realm/babel-plugin": "^0.1.1",
    "@types/react": "~18.2.13",
    "typescript": "^5.1.3"
  },
  "license": "Apache-2.0",
  "private": true
}

Cocoapods version

No response

Copy link

sync-by-unito bot commented Apr 11, 2024

➤ PM Bot commented:

Jira ticket: RJS-2799

@kneth
Copy link
Contributor

kneth commented Apr 12, 2024

@thegreatzeus Thank you for reporting. We need to investigate.

@favourwright
Copy link

favourwright commented Apr 12, 2024

I've literally been having same issue!
well, same error message
Classes extending Realm.Object cannot define their own schema static, all properties must be defined using TypeScript syntax

in my case I'm just trying to create a basic model like so

class Book extends Realm.Object<Book> {
  name!: string;
  price?: number;
  static schema: ObjectSchema = {
    name: 'Book',
    properties: {
      name: 'string',
      price: 'int?',
    },
  };
}

@favourwright
Copy link

@thegreatzeus any leads yet?

@jpbast
Copy link

jpbast commented Apr 15, 2024

Same issue here. Using @thegreatzeus class as example, if I just define my scheme as the following, it works fine

class Book extends Realm.Object<Book> {
  name?: string;
  price?: number;
}

If I add the static scheme: ObjectSchema { ... } code it always throw the error mentioned here. It seems the only way to set a primaryKey is through this ObjectSchema but with this error going on it's impossible.

Is there any work around so far?

@favourwright
Copy link

favourwright commented Apr 15, 2024

import { Realm } from '@realm/react'
import { BeneficiaryType } from '...'

export class Beneficiary extends Realm.Object {
  _id!: Realm.BSON.ObjectId;
  name!: string;
  ...

  static generate(payload: BeneficiaryType) {
    return {
      _id: new Realm.BSON.ObjectId(),
      name: payload.name,
      ....
    };
  }
}

Object.defineProperty(Beneficiary, 'schema', {
  value: {
    name: 'Beneficiary',
    primaryKey: '_id',
    properties: {
      _id: 'objectId',
      name: 'string',
      ...
    },
  },
});

this is what I ended up using @jpbast

@jpbast
Copy link

jpbast commented Apr 15, 2024

@favourwright it worked for me! Thanks for your quick reply

@elle-j
Copy link
Contributor

elle-j commented Apr 22, 2024

@thegreatzeus, it looks like you're using the @realm/babel-plugin. The idea of that plugin is to simplify some of the model/schema creation by removing the need for the explicit static schema field.

You can either remove the plugin and use the schema as you have defined it, or use the plugin and remove the static schema.

To index a property using the babel-plugin, use the @index annotation. To declare a primary key, use static primaryKey = _id (or whichever key is the pk).

The following is a similar example as the @realm/babel-plugin README:

class Task extends Realm.Object<Task, "description"> {
  _id = new Realm.BSON.ObjectId();
  description!: string;
  @index
  isComplete = false;

  static primaryKey = "_id";
}

@elle-j elle-j added the Waiting-For-Reporter Waiting for more information from the reporter before we can proceed label Apr 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants