fromResource

fromResource creates an observable whose current state can be inspected using .current(), and which can be kept in sync with some external datasource that can be subscribed to.

The created observable will only subscribe to the datasource if it is in use somewhere, (un)subscribing when needed. To enable fromResource to do that two callbacks need to be provided, one to subscribe, and one to unsubscribe. The subscribe callback itself will receive a sink callback, which can be used to update the current state of the observable, allowing observes to react.

Whatever is passed to sink will be returned by current(). The values passed to the sink will not be converted to observables automatically, but feel free to do so. It is the current() call itself which is being tracked, so make sure that you don’t dereference to early.

For inspiration, an example integration with the apollo-client on github, or the implementation of mobxUtils.now

The following example code creates an observable that connects to a dbUserRecord, which comes from an imaginary database and notifies when it has changed.

Parameters

  • subscriber
  • unsubscriber IDisposer (optional, default NOOP)
  • initialValue T the data that will be returned by get() until the sink has emitted its first data (optional, default undefined)

Examples

  1. function createObservableUser(dbUserRecord) {
  2. let currentSubscription;
  3. return fromResource(
  4. (sink) => {
  5. // sink the current state
  6. sink(dbUserRecord.fields)
  7. // subscribe to the record, invoke the sink callback whenever new data arrives
  8. currentSubscription = dbUserRecord.onUpdated(() => {
  9. sink(dbUserRecord.fields)
  10. })
  11. },
  12. () => {
  13. // the user observable is not in use at the moment, unsubscribe (for now)
  14. dbUserRecord.unsubscribe(currentSubscription)
  15. }
  16. )
  17. }
  18. // usage:
  19. const myUserObservable = createObservableUser(myDatabaseConnector.query("name = 'Michel'"))
  20. // use the observable in autorun
  21. autorun(() => {
  22. // printed everytime the database updates its records
  23. console.log(myUserObservable.current().displayName)
  24. })
  25. // ... or a component
  26. const userComponent = observer(({ user }) =>
  27. <div>{user.current().displayName}</div>
  28. )