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, defaultNOOP
)initialValue
T the data that will be returned byget()
until thesink
has emitted its first data (optional, defaultundefined
)
Examples
function createObservableUser(dbUserRecord) {
let currentSubscription;
return fromResource(
(sink) => {
// sink the current state
sink(dbUserRecord.fields)
// subscribe to the record, invoke the sink callback whenever new data arrives
currentSubscription = dbUserRecord.onUpdated(() => {
sink(dbUserRecord.fields)
})
},
() => {
// the user observable is not in use at the moment, unsubscribe (for now)
dbUserRecord.unsubscribe(currentSubscription)
}
)
}
// usage:
const myUserObservable = createObservableUser(myDatabaseConnector.query("name = 'Michel'"))
// use the observable in autorun
autorun(() => {
// printed everytime the database updates its records
console.log(myUserObservable.current().displayName)
})
// ... or a component
const userComponent = observer(({ user }) =>
<div>{user.current().displayName}</div>
)