BeTomorrow / micro-observables

A simple Observable library that can be used for easy state management in React applications.
MIT License
104 stars 8 forks source link

Handling nested observable that is possibly undefined #12

Closed danielrea closed 4 years ago

danielrea commented 4 years ago

Hello, This is not strictly a bug it's more of an edge case that i'm not sure how to handle or the best pattern to make it work.

Say I have an item that has a nested observable for quantitySelected. Just doing:

const selectedItem = useObservable(itemStore.selectedItem)
const selectedItemValue = useObservable(selectedItem.quantitySelected)

Will cause it to break when selectedItem is undefined.

I can fix this by having a conditional hook but, this will cause other issues due to this being an anti-pattern.

const selectedItem = useObservable(itemStore.selectedItem)
const selectedItemValue = selectedItem ? useObservable(selectedItem.quantitySelected) : 0

Would appreciate any help on this.

Thank you

simontreny commented 4 years ago

You can use transform() to return either the nested observable if it is defined or your default value. transform() will automatically "flatten" the result, so if it gets an observable, it'll return an observable with the value stored in the nested observable. Something like this should work well:

const selectedItemValue = useObservable(itemStore.selectedItem.transform(it => it.quantitySelected ?? 0))

For more complex cases, you can install micro-observables@next and use Observable.compute() or useComputedObservable():

const selectedItemValue = useComputedObservable(() => itemStore.selectedItem.get().quantitySelected?.get() ?? 0)
simontreny commented 4 years ago

Another solution would be this one:

const selectedItem = useObservable(itemStore.selectedItem)
const selectedItemValue = useObservable(selectedItem.quantitySelected ?? observable(0))

The (small) drawback of this solution is that your component will re-render every time selectedItem changes, even if quantitySelected has not changed.

danielrea commented 4 years ago

Thank you for the quick response and solutions!