Struct leptos::Action

source ·
pub struct Action<I, O>(/* private fields */)
where
    I: 'static,
    O: 'static;
Expand description

An action synchronizes an imperative async call to the synchronous reactive system.

If you’re trying to load data by running an async function reactively, you probably want to use a Resource instead. If you’re trying to occasionally run an async function in response to something like a user clicking a button, you’re in the right place.

async fn send_new_todo_to_api(task: String) -> usize {
    // do something...
    // return a task id
    42
}
let save_data = create_action(|task: &String| {
  // `task` is given as `&String` because its value is available in `input`
  send_new_todo_to_api(task.clone())
});

// the argument currently running
let input = save_data.input();
// the most recent returned result
let result_of_call = save_data.value();
// whether the call is pending
let pending = save_data.pending();
// how many times the action has run
// useful for reactively updating something else in response to a `dispatch` and response
let version = save_data.version();

// before we do anything
assert_eq!(input.get(), None); // no argument yet
assert_eq!(pending.get(), false); // isn't pending a response
assert_eq!(result_of_call.get(), None); // there's no "last value"
assert_eq!(version.get(), 0);
// dispatch the action
save_data.dispatch("My todo".to_string());

// when we're making the call
// assert_eq!(input.get(), Some("My todo".to_string()));
// assert_eq!(pending.get(), true); // is pending
// assert_eq!(result_of_call.get(), None); // has not yet gotten a response

// after call has resolved
assert_eq!(input.get(), None); // input clears out after resolved
assert_eq!(pending.get(), false); // no longer pending
assert_eq!(result_of_call.get(), Some(42));
assert_eq!(version.get(), 1);

The input to the async function should always be a single value, but it can be of any type. The argument is always passed by reference to the function, because it is stored in Action::input as well.

// if there's a single argument, just use that
let action1 = create_action(|input: &String| {
    let input = input.clone();
    async move { todo!() }
});

// if there are no arguments, use the unit type `()`
let action2 = create_action(|input: &()| async { todo!() });

// if there are multiple arguments, use a tuple
let action3 = create_action(|input: &(usize, String)| async { todo!() });

Implementations§

source§

impl<I, O> Action<I, O>
where I: 'static, O: 'static,

source

pub fn dispatch(&self, input: I)

Calls the async function with a reference to the input type as its argument.

source

pub fn new<F, Fu>(action_fn: F) -> Action<I, O>
where F: Fn(&I) -> Fu + 'static, Fu: Future<Output = O> + 'static,

Create an Action.

Action is a type of Signal which represent imperative calls to an asynchronous function. Where a Resource is driven as a function of a Signal, Actions are Action::dispatched by events or handlers.


let act = Action::new(|n: &u8| {
    let n = n.to_owned();
    async move { n * 2 }
});
act.dispatch(3);
assert_eq!(act.value().get(), Some(6));

// Remember that async functions already return a future if they are
// not `await`ed. You can save keystrokes by leaving out the `async move`

let act2 = Action::new(|n: &String| yell(n.to_owned()));
act2.dispatch(String::from("i'm in a doctest"));
assert_eq!(act2.value().get(), Some("I'M IN A DOCTEST".to_string()));

async fn yell(n: String) -> String {
    n.to_uppercase()
}
source

pub fn pending(&self) -> ReadSignal<bool>

Whether the action has been dispatched and is currently waiting for its future to be resolved.

source

pub fn set_pending(&self, pending: bool)

Updates whether the action is currently pending. If the action has been dispatched multiple times, and some of them are still pending, it will not update the pending signal.

source

pub fn url(&self) -> Option<String>

The URL associated with the action (typically as part of a server function.) This enables integration with the ActionForm component in leptos_router.

source

pub fn version(&self) -> RwSignal<usize>

How many times the action has successfully resolved.

source

pub fn input(&self) -> RwSignal<Option<I>>

The current argument that was dispatched to the async function. Some while we are waiting for it to resolve, None if it has resolved.

source

pub fn value(&self) -> RwSignal<Option<O>>

The most recent return value of the async function.

source§

impl<I> Action<I, Result<<I as ServerFn>::Output, ServerFnError<<I as ServerFn>::Error>>>
where I: ServerFn + 'static,

source

pub fn server( ) -> Action<I, Result<<I as ServerFn>::Output, ServerFnError<<I as ServerFn>::Error>>>
where I: ServerFn + Clone, <I as ServerFn>::Error: Clone + 'static,

Create an Action to imperatively call a server function.

The struct representing your server function’s arguments should be provided to the Action. Unless specified as an argument to the server macro, the generated struct is your function’s name converted to CamelCase.


// The type argument can be on the right of the equal sign.
let act = Action::<Add, _>::server();
let args = Add { lhs: 5, rhs: 7 };
act.dispatch(args);
assert_eq!(act.value().get(), Some(Ok(12)));

// Or on the left of the equal sign.
let act: Action<Sub, _> = Action::server();
let args = Sub { lhs: 20, rhs: 5 };
act.dispatch(args);
assert_eq!(act.value().get(), Some(Ok(15)));

let not_dispatched = Action::<Add, _>::server();
assert_eq!(not_dispatched.value().get(), None);

#[server]
async fn add(lhs: u8, rhs: u8) -> Result<u8, ServerFnError> {
    Ok(lhs + rhs)
}

#[server]
async fn sub(lhs: u8, rhs: u8) -> Result<u8, ServerFnError> {
    Ok(lhs - rhs)
}
source

pub fn using_server_fn( self ) -> Action<I, Result<<I as ServerFn>::Output, ServerFnError<<I as ServerFn>::Error>>>
where <I as ServerFn>::Error: Clone + 'static,

Associates the URL of the given server function with this action. This enables integration with the ActionForm component in leptos_router.

Trait Implementations§

source§

impl<I, O> Clone for Action<I, O>
where I: 'static, O: 'static,

source§

fn clone(&self) -> Action<I, O>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<I, O> Copy for Action<I, O>
where I: 'static, O: 'static,

Auto Trait Implementations§

§

impl<I, O> Freeze for Action<I, O>

§

impl<I, O> !RefUnwindSafe for Action<I, O>

§

impl<I, O> !Send for Action<I, O>

§

impl<I, O> !Sync for Action<I, O>

§

impl<I, O> Unpin for Action<I, O>
where I: Unpin, O: Unpin,

§

impl<I, O> !UnwindSafe for Action<I, O>

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more