Struct Eval

Source
pub struct Eval { /* private fields */ }
Expand description

§Communicating with JavaScript

You can use the eval function to execute JavaScript code in your application with the desktop, mobile, web or liveview renderers. Eval takes a block of JavaScript code (that may be asynchronous) and returns a Eval object that you can use to send data to the JavaScript code and receive data from it.

§Safety

Please be careful when executing JavaScript code with eval. You should only execute code that you trust. This applies especially to web targets, where the JavaScript context has access to most, if not all of your application data. Running untrusted code can lead to a cross-site scripting (XSS) vulnerability.

use dioxus::prelude::*;

fn App() -> Element {
    rsx! {
        button {
            onclick: move |_| async move {
                // Eval is a global function you can use anywhere inside Dioxus. It will execute the given JavaScript code.
                let result = document::eval(r#"console.log("Hello World");
                return "Hello World";"#);

                // You can use the `await` keyword to wait for the result of the JavaScript code.
                println!("{:?}", result.await);
            },
            "Log Hello World"
        }
    }
}

§Sending data to JavaScript

When you execute JavaScript code with eval, you can pass data to it by formatting the value into the JavaScript code or sending values to the Eval channel.

use dioxus::prelude::*;

fn app() -> Element {
    rsx! {
        button {
            onclick: move |_| {
                // You can pass initial data to the eval function by formatting it into the JavaScript code.
                const LOOP_COUNT: usize = 10;
                let eval = document::eval(&format!(r#"for(let i = 0; i < {LOOP_COUNT}; i++) {{
                    // You can receive values asynchronously with the the `await dioxus.recv()` method.
                    let value = await dioxus.recv();
                    console.log("Received", value);
                }}"#));

                // You can send values from rust to the JavaScript code with the `send` method on the object returned by `eval`.
                for i in 0..LOOP_COUNT {
                    eval.send(i).unwrap();
                }
            },
            "Log Count"
        }
    }
}

§Sending data from JavaScript

The Eval struct also contains methods for receiving values you send from JavaScript. You can use the dioxus.send() method to send values to the JavaScript code and the Eval::recv() method to receive values from the JavaScript code.

use dioxus::prelude::*;

fn app() -> Element {
    rsx! {
        button {
            onclick: move |_| async move {
                // You can send values from rust to the JavaScript code by using the `send` method on the object returned by `eval`.
                let mut eval = document::eval(r#"for(let i = 0; i < 10; i++) {
                    // You can send values asynchronously with the `dioxus.send()` method.
                    dioxus.send(i);
                }"#);

                // You can receive values from the JavaScript code with the `recv` method on the object returned by `eval`.
                for _ in 0..10 {
                    let value: i32 = eval.recv().await.unwrap();
                    println!("Received {}", value);
                }
            },
            "Log Count"
        }
    }
}

§Interacting with the DOM with Eval

You can also use the eval function to execute JavaScript code that reads or modifies the DOM. If you want to interact with the mounted DOM, you need to use eval inside the [dioxus_hooks::use_effect] hook which runs after the component has been mounted.

use dioxus::prelude::*;

const SCRIPT: &str = r#"
    let element = document.getElementById("my-element");
    element.innerHTML = "Hello World";
    return element.getAttribute("data-count");
"#;

fn app() -> Element {
    // ❌ You shouldn't run eval in the body of a component. This will run before the component has been mounted
    // document::eval(SCRIPT);

    // ✅ You should run eval inside an effect or event. This will run after the component has been mounted
    use_effect(move || {
        spawn(async {
            let count = document::eval(SCRIPT).await;
            println!("Count is {:?}", count);
        });
    });


    rsx! {
        div {
            id: "my-element",
            "data-count": "123",
        }
    }
}

Implementations§

Source§

impl Eval

Source

pub fn new(evaluator: GenerationalBox<Box<dyn Evaluator + 'static>>) -> Self

Create this eval from a dynamic evaluator

Source

pub async fn join<T: DeserializeOwned>(self) -> Result<T, EvalError>

Wait until the javascript task is finished and return the result

Source

pub fn send(&self, data: impl Serialize) -> Result<(), EvalError>

Send a message to the javascript task

Source

pub async fn recv<T: DeserializeOwned>(&mut self) -> Result<T, EvalError>

Receive a message from the javascript task

Trait Implementations§

Source§

impl IntoFuture for Eval

Source§

type Output = Result<Value, EvalError>

The output that the future will produce on completion.
Source§

type IntoFuture = Pin<Box<dyn Future<Output = <Eval as IntoFuture>::Output>>>

Which kind of future are we turning this into?
Source§

fn into_future(self) -> Self::IntoFuture

Creates a future from a value. Read more

Auto Trait Implementations§

§

impl Freeze for Eval

§

impl !RefUnwindSafe for Eval

§

impl !Send for Eval

§

impl !Sync for Eval

§

impl Unpin for Eval

§

impl !UnwindSafe for Eval

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<Ret> SpawnIfAsync<(), Ret> for Ret

Source§

fn spawn(self) -> Ret

Spawn the value into the dioxus runtime if it is an async block
Source§

impl<T, O> SuperFrom<T> for O
where O: From<T>,

Source§

fn super_from(input: T) -> O

Convert from a type to another type.
Source§

impl<T, O, M> SuperInto<O, M> for T
where O: SuperFrom<T, M>,

Source§

fn super_into(self) -> O

Convert from a type to another type.
Source§

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

Source§

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>,

Source§

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