Function leptos::create_resource

source ·
pub fn create_resource<S, T, Fu>(
    source: impl Fn() -> S + 'static,
    fetcher: impl Fn(S) -> Fu + 'static
) -> Resource<S, T>
where S: PartialEq + Clone + 'static, T: Serializable + 'static, Fu: Future<Output = T> + 'static,
Expand description

Creates a Resource, which is a signal that reflects the current state of an asynchronous task, allowing you to integrate async Futures into the synchronous reactive system.

Takes a fetcher function that generates a Future when called and a source signal that provides the argument for the fetcher. Whenever the value of the source changes, a new Future will be created and run.

When server-side rendering is used, the server will handle running the Future and will stream the result to the client. This process requires the output type of the Future to be Serializable. If your output cannot be serialized, or you just want to make sure the Future runs locally, use create_local_resource().

// any old async function; maybe this is calling a REST API or something
async fn fetch_cat_picture_urls(how_many: i32) -> Vec<String> {
  // pretend we're fetching cat pics
  vec![how_many.to_string()]
}

// a signal that controls how many cat pics we want
let (how_many_cats, set_how_many_cats) = create_signal(1);

// create a resource that will refetch whenever `how_many_cats` changes
let cats = create_resource(move || how_many_cats.get(), fetch_cat_picture_urls);

// when we read the signal, it contains either
// 1) None (if the Future isn't ready yet) or
// 2) Some(T) (if the future's already resolved)
assert_eq!(cats.get(), Some(vec!["1".to_string()]));

// when the signal's value changes, the `Resource` will generate and run a new `Future`
set_how_many_cats.set(2);
assert_eq!(cats.get(), Some(vec!["2".to_string()]));

We can provide single, multiple or even a non-reactive signal as source

// Single signal. `Resource` will run once initially and then every time `how_many_cats` changes
let async_data = create_resource(move || how_many_cats.get() , |_| async move { todo!() });
// Non-reactive signal. `Resource` runs only once
let async_data = create_resource(|| (), |_| async move { todo!() });
// Multiple signals. `Resource` will run once initially and then every time `how_many_cats` or `how_many_dogs` changes
let async_data = create_resource(move || (how_many_cats.get(), how_many_dogs.get()), |_| async move { todo!() });