-
Type: Improvement
-
Resolution: Unresolved
-
Priority: Major - P3
-
None
-
Affects Version/s: None
-
Component/s: Realm React
-
3 - M (<= 1 month)
-
6284
Problem
Users want the simples way possible to query their data, but the current useObject and useQuery APIs take the type as an argument, which could be simplified further.
Additionally, the current 3 positional argument layout of useQuery means users cannot rely on eslint rules to check for missing deps (see https://github.com/realm/realm-js/issues/6259).
Solution
A possible solution to both issues above, is to expose functions to generate class / type -aware hooks, which wouldn't require users to pass the type argument:
One example wrapping useQuery (proposed by @kraenhansen)
Unable to find source-code formatter for language: typescript. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
export const usePersons = createQueryHook<Person>("Person"); export const useDogs = createQueryHook<Dog>("Dog"); // ... and so on, one for every class in their schema // `createQueryHook` could even have an overload for class-based models, like some of our other APIs: export const usePersons = createQueryHook(Person); // And in a consuming component: const twenty = 20; const teenagers = usePersons(persons => persons.filtered("age < $0", twenty), [twenty]);
Another example handling both useQuery and useObject (proposed by @takameyer)
Unable to find source-code formatter for language: typescript. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
import {createModelHooks} from '@realm/react'; // or import {createModelHooks} from '../MyRealmContext'; class Person extend Realm.Object{} //some class based model const [usePersonById, usePerson] = createModelHooks(Person);
A third example where the user just have to pass model classes and the hooks are generated for them (proposed by @bimusiek)
Unable to find source-code formatter for language: typescript. Available languages are: actionscript, ada, applescript, bash, c, c#, c++, cpp, css, erlang, go, groovy, haskell, html, java, javascript, js, json, lua, none, nyan, objc, perl, php, python, r, rainbow, ruby, scala, sh, sql, swift, visualbasic, xml, yaml
enum SchemaName { Dog = 'Dog', Cat = 'Cat' } abstract class RealmModel { static schemaName: SchemaName; static get() { console.log('get'); } } class Dog extends RealmModel { static schemaName = SchemaName.Dog static woof() { console.log('woof'); } } class Cat extends RealmModel { static schemaName = SchemaName.Cat static meow() { console.log('meow') } } type SchemaWithModels = { [SchemaName.Cat]: typeof Cat; [SchemaName.Dog]: typeof Dog }; function createReactUtilities<Model extends typeof RealmModel>(models: Model[]) { type SchemaNameHooks = { [K in SchemaName as K extends string ? `use${K}` : never]: (callback: (query: SchemaWithModels[K]) => void, deps: any[]) => void } return models.reduce((hooks, model) => { return { ...hooks, [`use${model.schemaName}`]: (callback: any) => { callback(model); } } }, {}) as SchemaNameHooks; } const utils = createReactUtilities([Dog, Cat]); utils.useCat((query) => { query.get(); query.meow(); }, []) utils.useDog((query) => { query.get(); query.woof(); }, [])
Alternatives
Document and add to examples how users could use bind to create derived hooks:
const usePersons = useQuery.bind(null, Person);
How important is this improvement for you?
I would like to have it but have a workaround
Feature would mainly be used with
Atlas Device Sync