Closed markhuge closed 3 years ago
Hi! You actually don’t need to be that fancy in terms of channel use. When matching on the enter keypress in Update
you can just return the new model you want. So basically drop all the watching and channel stuff and…
Change this:
case "enter", " ":
l.ch <- itemModel{item: l.msgs[l.cursor], ch: l.ch}
To this:
case "enter", " ":
return itemModel{item: l.msgs[l.cursor]}, nil
Here’s the full file with the changes you can make, and here’s the diff.
As a side note, the reason the original code isn’t working is because the channel activity in Update
introduces a data race in which Update
is returning before the channel has had an opportunity to change the model. As a hard and fast rule, it's best to keep everything in Update
synchronous. If you need to run something asynchronously you can return a Cmd
, which will always run in a groutine under the hood.
I totally misunderstood what was happening with the returned model in #13's example. This is much simpler and nicer to use than I realized. Thanks!
:wave: Not sure if I'm just approaching this incorrectly. I'm building a UI with an index that has a list of items, and selecting the item drills down into the details for the item.
I created a top level model as recommended in #13, but because all my child models are dynamic, I was generating them and sending up to the parent via a channel. Here's a simplified, contrived example:
The models never seem to update. I've tried manually kicking off Init() and Update() after setting in Watch(), but no luck.
Is there some lifecycle event I'm missing? Am I just approaching this in a dumb way?