Realm-js: handling whitespaces in column names

Created on 18 Dec 2019  路  8Comments  路  Source: realm/realm-js

I can't find anything in documentations about how to filter on columns with whitespace in names.

Goals

do filtering on fields containing whitespaces.

Actual Results

Invalid predicate. exception

Code Sample

realm.objects('course').filtered('lessons list.@size == 2');

Version of Realm and Tooling

  • Node or React Native: ? Node
O-Community T-Enhancement

Most helpful comment

@noorzaie

But your UI tool opens the Realm right?

Using mapTo will not change the schema. Instead it adds an alias available only for your client while the Realm is opened. It could be a transformation of the name, that doesn't contain a whitespace such that it can be used in queries.

You could:

  1. Open the Realm to read its schema dynamically
  2. Go through the object schemas properties and transform all the names in the properties into camelCase, storing them as mapTo for each of the properties.
  3. Close the Realm and reopen it with the modified schema containing mapTos (which will not make any changes to the schema of the Realm file).
  4. Query using the mapTo property names instead of the ones containing whitespaces.

Example implementation

function openRealmMapped(config) {
  const realm = new Realm(config);
  const schema = realm.schema;
  realm.close();
  // Loop the object schemas and their properties
  for (const objectSchema of schema) {
    for (const [ name, property ] of Object.entries(objectSchema.properties)) {
      property.mapTo = camelCased(name);
    }
  }
  // Reopen with the modified schema, which does not change the schema store in the Realm file
  return new Realm({ ...config, schema });
}

Somewhere else ...

const realm = openRealmMapped({ path: 'whatever.realm' });
console.log(realm.schema);
// [ { name: "User", properties: { "first name": { type: "string", mapTo: "firstName" } } } ]
const john = realm.objects("User").filtered("firstName = 'John'")[0];

This might contain errors - as I havn't actually run it, but it should demonstrate the idea - does it? :)

All 8 comments

The query parser currently doesn't support properties with spaces. It's something we could add but it looks like this is the first I've seen of people using that so it seems to be an uncommon practice. Are you able to work around this for now by mapping the spaces in your property names to underscores or something else?
The query parser currently has the following limitations on property names:

  • properties must start with an alphabetic character (a-z, A-Z)
  • properties must contain only alphanumeric (a-z, A-Z, 0-9) or '_', '-', '$' characters

Hi. Thanks for answer. I'm working on a UI tool for realm, so I'm not owner of realm files and can't modify column names. Users may use whitespaces in their schemas, but as you said this is rare. No problem, thanks.

@noorzaie you might be interested in opening the Realm with a mapTo defined on the properties with names containing whitespaces.

See https://realm.io/docs/javascript/4.0.0.pre.beta.0/api/Realm.html#~ObjectSchemaProperty.

@kraenhansen Yes it is a possible method for who that created the schema, but as I said, I just want to represent user created realm files and don't want to edit. Thanks anyway.

@noorzaie

But your UI tool opens the Realm right?

Using mapTo will not change the schema. Instead it adds an alias available only for your client while the Realm is opened. It could be a transformation of the name, that doesn't contain a whitespace such that it can be used in queries.

You could:

  1. Open the Realm to read its schema dynamically
  2. Go through the object schemas properties and transform all the names in the properties into camelCase, storing them as mapTo for each of the properties.
  3. Close the Realm and reopen it with the modified schema containing mapTos (which will not make any changes to the schema of the Realm file).
  4. Query using the mapTo property names instead of the ones containing whitespaces.

Example implementation

function openRealmMapped(config) {
  const realm = new Realm(config);
  const schema = realm.schema;
  realm.close();
  // Loop the object schemas and their properties
  for (const objectSchema of schema) {
    for (const [ name, property ] of Object.entries(objectSchema.properties)) {
      property.mapTo = camelCased(name);
    }
  }
  // Reopen with the modified schema, which does not change the schema store in the Realm file
  return new Realm({ ...config, schema });
}

Somewhere else ...

const realm = openRealmMapped({ path: 'whatever.realm' });
console.log(realm.schema);
// [ { name: "User", properties: { "first name": { type: "string", mapTo: "firstName" } } } ]
const john = realm.objects("User").filtered("firstName = 'John'")[0];

This might contain errors - as I havn't actually run it, but it should demonstrate the idea - does it? :)

@kraenhansen That sounds great. Thanks so much for explanation and sample code. I'll try it.

@noorzaie Did it work for you?

@kneth I've not tested yet.

Was this page helpful?
0 / 5 - 0 ratings