Yew_route not Routing (v. 0.18.0, Yew: 0.21.0)

In my repo, branch introVideoImpl i attempt to use Yew's Route system. However I am stuck at this function:

pub fn exit_video(v: &Vec<Video>, video_index: UseStateHandle<usize>) -> Callback<KeyboardEvent> {
    

    let videos = v.clone();
    let current_video_index =  video_index;
    //let current_video_index = use_state(|| 0);

    Callback::from(move |event: KeyboardEvent| {
        if event.key() == "x"{
            let new_route = Route::MainMenu.into();
            let navigator = use_navigator();
            
            Switch::into(new_route).send();
        }
    })
}

I've tried to use: let navigator = use_navigator().unwrap(); from Yew-route examples, but it also wont let me unwrap the Option.

Help much appreciated, thanks. :sunflower:

What's the error message? Have you tried creating the navigator outside of the Callback closure?

The error message is:

let new_route = Route::MainMenu.into();
                                ^^^^ the trait `From<Route>` is not implemented for `yew_router::Switch<_>`

I get the same error when I move it outside.

If you want to go to the home page if your user presses x (from a UI perspective I'd find it a lot more desirable to go back one page using Navigator::back, not directly to the home screen), I think your Callback should look something like this:

    Callback::from(move |event: KeyboardEvent| {
        if event.key() == "x"{
            let navigator = use_navigator().unwrap();
            navigator.push(Route::MainMenu);
        }
    })

Switch is a component you want to use like it is in this example.

Yes, I agree Switch was a desperate attempt. :sweat_smile:

I get this error with the .unwrap() in this code:

no method named `unwrap` found for opaque type `impl Hook<Output = Option<Navigator>> + '_` in the current scope
method not found in `impl Hook<Output = Option<Navigator>>`

is it becaurse it's not wrapped inside a #[function_component(MyComponent)] like in this example?

I have successfully implemented the Switch statement in my Lib.rs file:

use yew::functional::*;
use yew::prelude::*;
use yew_router::prelude::*;
use components::molecules::video_list::VideosList;
use components::data::video_data::*;
use components::organisms::keydown_logic::get_toggle_key;
use crate::components::organisms::intro_screen::IntroScreen;


mod components;




#[derive(Clone, Routable, Debug, PartialEq)]
pub enum Route {
    #[at("/home")]
    Home,
    #[at("/main-menu")]
    MainMenu,
    #[at("/intro-screen")]
    IntroScreen2,
    #[at("/")]
    IntroScreen1,
}


#[function_component(DanceOmatic)]
pub fn app() -> Html {


    html! {
    <div>
        <BrowserRouter>
            <Switch<Route> render={switch} />
        </BrowserRouter>
    </div>
    }
}

fn switch(routes: Route) -> Html {
    match routes {
        Route::Home => html! { <h1>{ "Home" }</h1> },
        Route::MainMenu => html! { <h1>{ "Main" }</h1> },
        Route::IntroScreen1 => html! {
            <IntroScreen />
        },
        Route::IntroScreen2 => html! {
            <IntroScreen />
        },
    }
}

Exactly, your callback is neither a component nor a hook, which is why you can't just call .unwrap() on it. That's why I suggested creating navigator outside of the closure in a component and then pass the Navigator to Callback, like they do in the example you've linked.

I got it solved by creating it like this:

#[function_component(IntroScreen)]
pub fn intro_screen() -> Html {
    let navigator = use_navigator().unwrap();
    let intro_video = get_intro_video();
    let current_video_index = use_state(|| 0);

    let press_x_for_main = Callback::from(move |event: KeyboardEvent| {
        if event.key() == "x"{
        navigator.push(&Route::MainMenu);
        }});


    html! {
        <div onkeydown={press_x_for_main} tabindex="0">
            <VideosList videos={intro_video} current_index={*current_video_index} />
        </div>
    }
}

Thanks for your help @jofas :sunny:

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.