What is the recommended way to inject data, such as a URL to hit for configuration etc, when initializing seed? What I'd love to do is provide a JavaScript object or values to the render function and then use that to create the initial Model. Sorta like the Elm flags idea (https://guide.elm-lang.org/interop/flags.html). This way I could have the app behave slightly different depending on the environment it gets initialized with such as hit the QA server not Prod when loading the page in the QA environment or turn on a debug mode when necessary. The AfterMount API limits me from using a closure with passed in data or at least I have yet to figure out how to.
So what is the best way to accomplish my goal?
If you're pulling data from the server (ie using JSON/Rest format), you could try a pattern like this:
fn get_data() -> impl Future<Item = Msg, Error = Msg> {
let url = "/get-data/";
seed::Request::new(url).fetch_json_data(Msg::LoadedInitial)
}
#[derive(Clone, Debug, Deserialize)]
struct ServerData {
field1: u32,
// ...
}
#[derive(Default)]
struct Model {
field1: u32,
// ...
}
#[derive(Clone)]
enum Msg {
LoadedInitial(seed::fetch::ResponseDataResult<ServerData>),
}
fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
match msg {
Msg::LoadedInitial(Ok(data)) => {
model.field1 = data.field1,
// ...
}
Msg::LoadedInitial(Err(fail_reason)) => {
error!(format!(
"Fetch error - Fetching initial data failed - {:#?}",
fail_reason
));
orders.skip();
}
}
// ...
fn after_mount(_: Url, orders: &mut impl Orders<Msg>) -> AfterMount<Model> {
orders.perform_cmd(get_data());
AfterMount::default()
}
To load an initial model from JS, you could use something like this:
fn after_mount(_: Url, orders: &mut impl Orders<Msg>) -> AfterMount<Model> {
AfterMount::new(getJsData())
}
#[wasm_bindgen]
extern "C" {
fn getJsData() -> Model;
}
// Assuming you have a js function defined before the Seed app called `getJsData`.
Does this answer your question? If not, could you provide more details?
The "load an initial model form JS" is what i was trying to do and your suggestion worked perfectly! I was trying to somehow fit it inside the render function but your suggestion makes sense.
Thanks! for the answer I love using seed so far!
Glad it worked; I'll add that example to the guide.