Skip to content
This repository has been archived by the owner on Nov 26, 2018. It is now read-only.

Commit

Permalink
fix(connectObs): unsubscribe from observables when unmounting (#92)
Browse files Browse the repository at this point in the history
  • Loading branch information
matthieuprat authored and gregberge committed Dec 12, 2017
1 parent 6d3650a commit 2caf2a1
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 10 deletions.
4 changes: 4 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
semi: false
trailingComma: all
printWidth: 80
singleQuote: true
24 changes: 24 additions & 0 deletions src/__tests__/connectObs.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,4 +143,28 @@ describe('connectObs', () => {
)
expect(wrapper.equals(<div className="foo" />)).toBeTruthy()
})

it('unsubscribes from observables when the enhanced component is unmounted', () => {
const spy = jest.fn()
const spyUnsubscribe = observable =>
Rx.Observable.create(observer => {
const subscription = observable.subscribe(observer)
return () => {
spy()
subscription.unsubscribe()
}
})

const Component = compose(
connectObs(({ props$ }) => ({
foo: spyUnsubscribe(Rx.Observable.never()),
props: spyUnsubscribe(props$),
})),
)('div')

const wrapper = shallow(<Component />)
expect(spy).toHaveBeenCalledTimes(0)
wrapper.unmount()
expect(spy).toHaveBeenCalledTimes(2)
})
})
33 changes: 23 additions & 10 deletions src/connectObs.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,11 @@ const connectObs = obsMapper =>
withObs(observables => {
const nextProps$ = createObservable(observer => {
const obsMap = obsMapper(observables)
checkObsMap(obsMap)
let props
const obsProps = {}
const obsSubscriptions = []
let props

checkObsMap(obsMap)

const update = () => {
if (props) {
Expand All @@ -84,23 +86,34 @@ const connectObs = obsMapper =>
const observable = obsConfig.toESObservable(obsMap[key])
checkObservable(observable, key)
obsProps[key] = undefined
observable.subscribe({
const subscription = observable.subscribe({
next(value) {
obsProps[key] = value
update()
},
error: asyncThrow,
})

obsSubscriptions.push(subscription)
}
})

obsConfig.toESObservable(observables.props$).subscribe({
next(nextProps) {
props = nextProps
update()
},
error: asyncThrow,
})
const propsSubscription = obsConfig
.toESObservable(observables.props$)
.subscribe({
next(nextProps) {
props = nextProps
update()
},
error: asyncThrow,
})

return () => {
propsSubscription.unsubscribe()
obsSubscriptions.forEach(subscription => {
subscription.unsubscribe()
})
}
})

return { props$: nextProps$ }
Expand Down

0 comments on commit 2caf2a1

Please sign in to comment.