Am I using observable-hooks correctly? #134
-
Hi, I am new to rxjs & observable-hooks and was wondering if I was using these libraries correctly. Please see my example below (full code here). This code fetches some movies using
export function MovieMagicBehaviorSubject() {
// RxJS state is stored here in BehaviorSubject
const movies$ = useMemo(() => new BehaviorSubject<Movie[]>([]), []);
const loading$ = useMemo(() => new BehaviorSubject<boolean>(true), []);
const error$ = useMemo(
() => new BehaviorSubject<string | undefined>(undefined),
[],
);
// Connect RxJS state to React state using useObservableState
const movies = useObservableState<Movie[]>(movies$, []);
const loading = useObservableState<boolean>(loading$, true);
const error = useObservableState<string | undefined>(error$, undefined);
useEffect(() => {
// Create an Observable that fetches top 10 movies
const data$ = fromFetch(
'https://movie-magic-rest-api-221d9114e329.herokuapp.com/movies?sort=RANK_ASC&page=1&perPage=10',
{
selector: async (response) => response.json(),
},
);
// Subscribe to the data$ observable
const data$Subscription = data$.subscribe({
next: (response) => {
movies$.next(response.movies as Movie[]);
loading$.next(false);
},
error: (error: Error) => {
error$.next(error.message);
loading$.next(false);
},
});
return () => {
data$Subscription.unsubscribe();
};
}, [error$, loading$, movies$]);
...
return <MovieList movies={movies} />;
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 4 replies
-
Hi, I would not recommend using // Subscribe to the data$ observable
const data$Subscription = data$.subscribe({
next: (response) => {
movies$.next(response.movies as Movie[]);
loading$.next(false);
},
error: (error: Error) => {
error$.next(error.message);
loading$.next(false);
},
}); This is not a very idiomatic way to write RxJS. In RxJS you normally consume the value at the end of a flow by subscribing it. If you want to change the value in the flow or move it to a new flow, you generally Here if you want to reproduce import { switchMap, catchError, startWith } from "rxjs";
import { fromFetch } from "rxjs/fetch";
import { useObservable, useObservableState } from "observable-hooks";
function useQuery(url) {
const result$ = useObservable(
inputs$ => inputs$.pipe(
// switchMap will auto-cancel the last subflow so you don't get stale responses.
switchMap(([url]) => fromFetch(url).pipe(
switchMap(async response => {
if (response.ok) {
return { data: await response.json(), isLoading: false };
} else {
return { error: `Error ${response.status}`, isLoading: false };
}
}),
// catch error in subflow so that error won't kill the main flow
catchError(err => of({ error: err.message, isLoading: false })),
)),
startWith({ isLoading: true })
),
[url]
);
return useObservableState(result$);
} |
Beta Was this translation helpful? Give feedback.
Hi, I would not recommend using
BehaviorSubject
for state management in React. There are better options like Signals. RxJS as far as I am concerned is more suitable for orchestrating sequence of asynchronous operations.This is not a very idiomatic way to write RxJS. In RxJS you normally consume the value at the end of a flow by subscribing it. If you want to change the va…