diff --git a/examples/dog_app.rs b/examples/dog_app.rs index 410f335f4..fa616692b 100644 --- a/examples/dog_app.rs +++ b/examples/dog_app.rs @@ -7,32 +7,37 @@ fn main() { fn app() -> Element { let breed = use_signal(|| "deerhound".to_string()); - let breed_list = use_future(|| async move { - reqwest::get("https://dog.ceo/api/breeds/list/all") + let list = reqwest::get("https://dog.ceo/api/breeds/list/all") .await .unwrap() .json::() - .await + .await; + + let Ok(breeds) = list else { + return rsx! { "error fetching breeds" }; + }; + + rsx! { + for cur_breed in breeds.message.keys().take(10).cloned() { + li { key: "{cur_breed}", + button { onclick: move |_| breed.set(cur_breed.clone()), + "{cur_breed}" + } + } + } + } }); match breed_list.value().read().as_ref() { - Some(Ok(breeds)) => rsx! { - div { height: "500px", - h1 { "Select a dog breed!" } - div { display: "flex", - ul { flex: "50%", - for cur_breed in breeds.message.keys().take(10).cloned() { - li { key: "{cur_breed}", - button { onclick: move |_| breed.set(cur_breed.clone()), "{cur_breed}" } - } - } - } - div { flex: "50%", BreedPic { breed } } - } + Some(resp) => rsx! { + h1 { "Select a dog breed!" } + div { height: "500px", display: "flex", + ul { flex: "50%", {breed_list} } + div { flex: "50%", BreedPic { breed } } } }, - _ => rsx! { div { "loading breeds" } }, + _ => rsx! { "loading breeds..." }, } } @@ -53,7 +58,7 @@ fn BreedPic(breed: Signal) -> Element { img { max_width: "500px", max_height: "500px", src: "{resp.message}" } } }, - _ => rsx! { div { "loading dog picture" } }, + _ => rsx! { "loading image..." }, } } diff --git a/packages/core/src/global_context.rs b/packages/core/src/global_context.rs index f81c05f6f..d4d6d533a 100644 --- a/packages/core/src/global_context.rs +++ b/packages/core/src/global_context.rs @@ -27,7 +27,10 @@ pub fn try_consume_context() -> Option { pub fn consume_context() -> T { with_current_scope(|cx| cx.consume_context::()) .flatten() - .unwrap_or_else(|| panic!("Could not find context {}", std::any::type_name::(),)) + .expect(&format!( + "Could not find context {}", + std::any::type_name::(), + )) } /// Consume context from the current scope diff --git a/packages/hooks/src/use_coroutine.rs b/packages/hooks/src/use_coroutine.rs index 31f10897e..c49b7eac3 100644 --- a/packages/hooks/src/use_coroutine.rs +++ b/packages/hooks/src/use_coroutine.rs @@ -1,4 +1,4 @@ -use dioxus_core::prelude::{consume_context, provide_context, push_future, use_hook}; +use dioxus_core::prelude::{consume_context, provide_context, spawn, use_hook}; use dioxus_core::Task; use dioxus_signals::{CopyValue, Signal}; pub use futures_channel::mpsc::{UnboundedReceiver, UnboundedSender}; @@ -83,7 +83,7 @@ where // this might not be the best API if *coroutine.needs_regen.read() { let (tx, rx) = futures_channel::mpsc::unbounded(); - let task = push_future(init(rx)).unwrap(); + let task = spawn(init(rx)); coroutine.tx.set(Some(tx)); coroutine.task.set(Some(task)); coroutine.needs_regen.set_untracked(false); diff --git a/packages/hooks/src/use_future.rs b/packages/hooks/src/use_future.rs index ca26c82b9..418052076 100644 --- a/packages/hooks/src/use_future.rs +++ b/packages/hooks/src/use_future.rs @@ -3,7 +3,7 @@ use dioxus_core::{ prelude::{spawn, use_hook}, ScopeState, Task, }; -use dioxus_signals::{use_effect, use_signal, Signal}; +use dioxus_signals::{use_effect, use_signal, Effect, Signal}; use futures_util::{future, pin_mut, FutureExt}; use std::{any::Any, cell::Cell, future::Future, pin::Pin, rc::Rc, sync::Arc, task::Poll}; @@ -20,7 +20,7 @@ use std::{any::Any, cell::Cell, future::Future, pin::Pin, rc::Rc, sync::Arc, tas /// will be canceled before the new one is started. /// /// - dependencies: a tuple of references to values that are PartialEq + Clone -pub fn use_future(future: impl FnMut() -> F) -> UseFuture +pub fn use_future(mut future: impl FnMut() -> F) -> UseFuture where T: 'static, F: Future + 'static, @@ -34,8 +34,8 @@ where // Spawn a wrapper task that polls the innner future and watch its dependencies let task = spawn(async move { - // move the future here and pin it so we can ppoll it - let mut fut = fut; + // move the future here and pin it so we can poll it + let fut = fut; pin_mut!(fut); let res = future::poll_fn(|cx| { @@ -44,7 +44,7 @@ where // Poll the inner future let ready = fut.poll_unpin(cx); - // add any dependencies to the effect stack + // add any dependencies to the effect stack that we need to watch when restarting the future ready }) @@ -85,15 +85,14 @@ impl UseFuture { // Manually set the value in the future slot without starting the future over pub fn set(&self, new_value: T) { - // self.state.set(Some(new_value)); + self.value.set(Some(new_value)); } /// Return any value, even old values if the future has not yet resolved. /// /// If the future has never completed, the returned value will be `None`. pub fn value(&self) -> Signal> { - todo!() - // self.state.current_val.as_ref().as_ref() + self.value } /// Get the ID of the future in Dioxus' internal scheduler diff --git a/packages/signals/src/effect.rs b/packages/signals/src/effect.rs index c4d201762..c8fcdd1e8 100644 --- a/packages/signals/src/effect.rs +++ b/packages/signals/src/effect.rs @@ -26,7 +26,7 @@ impl EffectStack { } pub(crate) fn get_effect_stack() -> EffectStack { - match consume_context() { + match try_consume_context() { Some(rt) => rt, None => { let store = EffectStack::default(); diff --git a/packages/signals/src/rt.rs b/packages/signals/src/rt.rs index 30e4439e0..ae1f13155 100644 --- a/packages/signals/src/rt.rs +++ b/packages/signals/src/rt.rs @@ -12,7 +12,7 @@ use generational_box::{ use crate::Effect; fn current_store() -> Store { - match consume_context() { + match try_consume_context::() { Some(rt) => rt, None => { let store = Store::default();