I'm new to Rust and Tauri and just created an app using cargo create-tauri-app and wanted to add a thread in Rust emitting a global event that is used to change a text in the frontend. However, I cannot make it work. This is my code:
index.html
(just adding a p
-Element #test-msg
)
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="styles.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tauri App</title>
<script type="module" src="/main.js" defer></script>
</head>
<body>
<main class="container">
<h1>Welcome to Tauri</h1>
<div class="row">
<a href="https://tauri.app" target="_blank">
<img src="/assets/tauri.svg" class="logo tauri" alt="Tauri logo" />
</a>
<a
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript"
target="_blank"
>
<img
src="/assets/javascript.svg"
class="logo vanilla"
alt="JavaScript logo"
/>
</a>
</div>
<p>Click on the Tauri logo to learn more about the framework</p>
<form class="row" id="greet-form">
<input id="greet-input" placeholder="Enter a name..." />
<button type="submit">Greet</button>
</form>
<p id="greet-msg">Hallo1</p>
<p id="test-msg">Hallo2</p>
</main>
</body>
</html>
main.js
(adding testMsgEl
, listen to events)
const { invoke } = window.__TAURI__.core;
const { listen } = window.__TAURI__.event.listen;
let greetInputEl;
let greetMsgEl;
let testMsgEl;
async function greet() {
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
greetMsgEl.textContent = await invoke("greet", { name: greetInputEl.value });
}
listen<String> ('emit_from_rust', (event) => {
testMsgEl.textContent = event.payload;
});
window.addEventListener("DOMContentLoaded", () => {
greetInputEl = document.querySelector("#greet-input");
greetMsgEl = document.querySelector("#greet-msg");
testMsgEl = document.querySelector("#test-msg");
document.querySelector("#greet-form").addEventListener("submit", (e) => {
e.preventDefault();
greet();
});
});
lib.rs
(I added the function test_emit
and started it using .setup
)
use std::{thread::sleep, time::Duration};
use tauri::{AppHandle, Emitter};
// Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
#[tauri::command]
fn greet(name: &str) -> String {
format!("Hello, {}! You've been greeted from Rust!", name)
}
fn test_emit(handle: AppHandle) {
std::thread::spawn(move || {
for i in 1..4 {
sleep(Duration::from_secs(1));
handle.emit("emit_from_rust", &format!("{i}!")).unwrap();
}
});
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_shell::init())
.invoke_handler(tauri::generate_handler![greet])
.setup(|app| {
let handle = app.handle().clone();
test_emit(handle);
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
I found the problem:
const { listen } = window.__TAURI__.event.listen;
and then using listen does not work. Instead, using
window.__TAURI__.event.listen('emit_from_rust', (event) => {
testMsgEl.innerHTML = event.payload;
});
directly in the code just does what I wanted it to do.