Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

@nozbe/with-observables

Nozbe13.2kMIT1.6.0TypeScript support: included
react, react-native, hoc, reactive, rxjs, observable, watermelondb

readme

withObservables

MIT License CI Status npm

A higher-order component for connecting RxJS Observables to React components.

Example

(Taken from WatermelonDB)

const Post = ({ post, comments }) => (
  <article>
    <h1>{post.name}</h1>
    <p>{post.body}</p>
    <h2>Comments</h2>
    {comments.map(comment =>
      <EnhancedComment key={comment.id} comment={comment} />
    )}
  </article>
)

const enhance = withObservables(['post'], ({ post }) => ({
  post: post.observe(),
  comments: post.comments.observe()
}))

const EnhancedPost = enhance(Post)

➡️ Learn more: Connecting WatermelonDB to Components

Installation

yarn add @nozbe/with-observables

And then to use:

import withObservables from '@nozbe/with-observables'

Usage

withObservables(triggerProps, getObservables)

// Injects new props to a component with values from the passed Observables
//
// Every time one of the `triggerProps` changes, `getObservables()` is called
// and the returned Observables are subscribed to.
//
// Every time one of the Observables emits a new value, the matching inner prop is updated.
//
// You can return multiple Observables in the function. You can also return arbitrary objects that have
// an `observe()` function that returns an Observable.
//
// The inner component will not render until all supplied Observables return their first values.
// If `triggerProps` change, renders will also be paused until the new Observables emit first values.
//
// If you only want to subscribe to Observables once (the Observables don't depend on outer props),
// pass `null` to `triggerProps`.
//
// Errors are re-thrown in render(). Use React Error Boundary to catch them.
//
// Example use:
//   withObservables(['task'], ({ task }) => ({
//     task: task,
//     comments: task.comments.observe()
//   }))

Typescript

The TypeScript bindings expose a helper type, ObservableifyProps<Props, ObservableKeys, ObservableConvertibleKeys> which can make it easier to wrap components without duplicating interfaces:

interface Props {
  post: Post;
  author: Author;
  someOtherProp: boolean;
  anotherProp: number;
}

const PostRenderer: React.FC<Props> = (props) => ( ... );

type InputProps = ObservableifyProps<Props, "author", "post">
const enhance = withObservables(["post", "author"], ({ post }: InputProps) => ({
  post,
  author: author.observe()
});

export default enhance(PostRenderer);

Or you can let getObservables define your props for you:

import withObservables, {ExtractedObservables} from "@nozbe/with-observables"

const getObservables = ({ post }: { post: Post }}) => ({
  post,
  author: author.observe()
});

interface Props extends ExtractedObservables<ReturnType<typeof getObservables>> {
  someOtherProp: boolean;
  anotherProp: number;
}

const PostRenderer: React.FC<Props> = (props) => (
  <>{props.author.id}</>
);

export default withObservables(["post"], getObservables)(PostRenderer);

Author and license

withObservables was created by @Nozbe for WatermelonDB.

withObservables' main author and maintainer is Radek Pietruszewski (websitetwitterengineering posters)

See all contributors.

withObservables is available under the MIT license. See the LICENSE file for more info.

changelog

Changelog

All notable changes to this project will be documented in this file.

1.6.0 - 2023-06-12

NOTE: We will be abandoning a standalone @nozbe/withObservables package and merging it into @nozbe/watermelondb. This might be the last release of this package.

If you're using withObservables WITHOUT WatermelonDB, please file an issue. If there's enough demand for a standalone package, we'll consider maintaining it.

  • Update react, @types/react peer dependencies to allow React 18. This fixes issues by NPMv7 users
  • Fix Flow issues when running Flow 0.199.1
  • Fix Flow issues when in exact_by_default mode
  • Bump hoist-non-react-statics dependency
  • Mark @types/hoist-non-react-statics and @types/react peer dependencies as optional (for non-TS users)
  • Remove unused _isMounted property
  • Internal: bump all dependencies

1.4.1 - 2022-08-31

  • Fix Flow issues when running Flow 0.185.2

1.4.0 - 2021-06-28

  • add helpful Component.displayName to make it easier to distinguish between withObservables in React DevTools

1.3.0 - 2021-04-07

  • use WatermelonDB 0.22 api to differentiate between Model and Query objects
  • fix warnings when using React 17

1.2.0 - 2021-03-25

  • Observable errors are now re-thrown in render, so that you can catch them with an Error Boundary
  • withObservable no longer has a dependency on RxJS package, which makes it leaner, more performant and should hopefully fix persistent issues with rxjs-compat that some users have

1.0.8 - 2020-12-17

  • Fix Flow issues when running Flow 0.140.0

1.0.7 - 2020-10-27

  • Improve performance
  • Name functions for easier debugging / profiling
  • Fix RxJS issue

1.0.5 - 2019-08-10

  • Fix Typescript bindings

1.0.4 - 2019-08-02

  • Add Typescript bindings

1.0.3 - 2019-03-14

  • Add hoist-non-react-statics

1.0.2 - 2018-10-26

  • [Flow] Fixed types for Flow 0.84.0

1.0.1 - 2018-09-19

Fixed

  • Fixed Flow typings for withObservables (this now works without any setup)
  • Fixed Flow for injecting props using WatermelonDB Relation objects (skipping .observe())

1.0.0 - 2018-09-07

Initial release of withObservables HOC