YEW Megatutorial — Tut 02: Extending the example
In this second part we are going to do some extensions/improvements, and hopefully show a little more the potential of the Yew framework
In this article we will be tinkering around, in order to understand better the concepts at work in Yew. We will do also some project related stuff, which is more general or more frontend specific, and less related with Yew. Let’s go!
The code has been tagged with the relative tutorial and part.
https://gist.github.com/86ff62498719dd1709466870f928e70b
Let’s script our way through the boring stuff
But first a little improvement that will help us a lot. Let’s create a file called run.sh
This script’s’ purpose is simple: automate the build and run of this project.
https://gist.github.com/a630a1a3bb8e12180fa1d92d28841661
At the top of the script we have the shebang, #!/bin/sh
,that tell the console interpreter which environment use. Of course, sh is not bash, but as long as you are posix compliant in your scripts, it doesn't matter. I personally use zsh with the fabulous Oh My Zsh!, but these are personal preferences. Back to work, now.
We divided the actions to be done in 3 functions that we call at the end. It is important to be modular, because in this way we can modify independently each one of the functions.
- the function build calls up the
wasm-pack
as we have seen in the previous post - the function pack calls up the
rollup
as seen in the previous post.
The run function deserves special attention. We are not simply calling the server, we are making it work in background (the &
appended to the command). For this reason we are saving the process' PID and storing it in a hidden file, .serverpid
Quick troubleshooting: if you have both python2 and python3 installed on your system, and the script is not working, saying it can’t recognize the http module
https://gist.github.com/69615312d60924b5c4b8a3dc14c2c0d6
try calling straight python 3, for example python -m "http.server" "8080" &
Now that it is done, let’s make it executable.
https://gist.github.com/17f57fc33437cf9cba47bf20038e676e
Finally we can execute it easily with:
https://gist.github.com/e7296a1c8e14851a041c22ea3593689b
Yatta! All working well. But if we wish to stop the server? We need to look at the process’ pid we stored earlier
https://gist.github.com/aa056f8c26932e35d2b0b98ca4135680
Right now for me is 10859
I can stop it, therefore with:
https://gist.github.com/5c07ab2cdd0b369c27b9a56d2babf236
Done!
Now we’d better make an automated script to do just that-
The script is modular as well, maybe its overkill, but better be prepared for more.
https://gist.github.com/8e1aa4145b4841853cd67dde31115678
- We check for the existence of .serverpid and we kill the process with the pid written in it
- We alert the user both in the case the pid was not found and in the case all went well.
Now we have two scripts to help us going on with the project (remember to make stop.sh executable!)
Extending our example app
After this detour we can go on with the Yew tutorial. Without further ado, let’s thinker around with the code inside our src/app.rs
Code to follow this part
https://gist.github.com/d3433ce1ab3eeda6f8ac23de3a21efbe
First of all, let’s add a new message, let’s say, to decrease the counter.
https://gist.github.com/900b443ab29bf74d5b3a18a1ad4dce10
Now we need to take care of handling the logic of this new message:
https://gist.github.com/ba933e224192cc3ad41ae91bcb0c85dc
Quite simply, we added a match branch and we did something with that message.
It is now time to add a button to the DOM, in order to send this new message.
https://gist.github.com/c37f0bc16cedcc4b0aa2d7f9857b71ee
This too is quite self-explanatory. Let’s check it out starting the server.
Well good. We can even go negative if we want. What about implementing the logic to avoid negative numbers, but stop to 0
? Can you implement it? (My solution in code)
Code to follow this part
https://gist.github.com/2ff68955322bd451d5b39ead32e5600f
What if we want the counter instead to be a list, and increase the elements of that list? This is plain ol’Rust, let’s do it!
First of all, let’s modify counter to be a Vec<i64>
. Actually, the name "counter does not make sense anymore, so let's rename the symbol too:
https://gist.github.com/bbafe591dc18bcf40d5bdef2ab51f973
We need to update our component constructor as well, the create function:
https://gist.github.com/9b4a0a5f301a69cd86bcb760403245bd
Of course, we can’t simply add to the a Vec
, we need to update the update logic! Well... What are we going to push inside of it? For now just a random number!
Wait! How do we add a random number? We need first of all get into our dependencies the crate rand, which supports compiling to the WASM through getrandom
In Cargo.toml add to the [dependencies]
:
https://gist.github.com/32b94e202f9deaf3dc95ed408586aa1f
To call the random()
function, we have to use
the preamble in src/app.rs
https://gist.github.com/06715ee9da71e4ed13bf68695fc61354
Then we can change the handling logic in update
:
https://gist.github.com/f5fea2b0ee27d82d5f85bf3ab0adea4f
Why would we need to wrap the remove branch of the match
in brackets? Remember that pop()
returns an Option (the popped element or None
), while push returns ()
.
Finally we have to display our trusty vec:
https://gist.github.com/cf0c4e6d19a28a9ac9f5076c5a10dcd0
A vector does not implement Display, so we take advantage of the debug formatting. In fact, all handy tools are still available to us: Rust’s still Rust even compiled to WASM.
We can now run and check the results.
Well, I did add some random items.
OK, but should we not do something useful instead of just Rusting around? Hold your horses cowboy, we first need some more understanding of how to work in Rust with WASM, and the Yew framework.
Code to follow this part
https://gist.github.com/b078bccd27933194754eec56e98faca2
Rust’s format!
is great and all, but sure displaying a vec in debug mode is not that great frontend practice, is it?
Let’s remedy to that, by changing our view
https://gist.github.com/bc524a7a3c7d8e9d3806120a1e41780b
Whaaat? Stop the world it’s spinning too fast!
We are using a CSS framework here, picnic, and we are using a recursion over the vector in order to create rows of a table.
Lets go in order. We added a lot of HTML tags and CSS classes, but really what has changed is just the following:
https://gist.github.com/346d50a64dc40878e279fa827d610f85
This notation starting with a for iterates over the vec self.items
and maps the results to a closure, render_item.
Let’s see what this closure does, then.
https://gist.github.com/796bc5c020d81c6558f4059aed5feec7
This closure returns a html!
using fragments.
Fragments are a couple of empty tags <>
and </>
. This is the way Yew has to nest code for html!
inside another. Since this macro can have just one starting point in the DOM, fragments manage the nesting for us.
For the rest, there is really no other new thing, except for a lot of new HTML and CSS classes. And a little caveat:
https://gist.github.com/89c6dceb4f9b581682d1b57387b5dde8
This fragment between the two buttons is really important, in order to let Yew play nice with picnic buttons.
Before running the project we have to remember to update the index.html as well, in order to call picnic
, otherwise there is no point in all those CSS classes.
https://gist.github.com/4865b9539870a1eb9655c7a703c32b03
I added 2 styles as well, just to show that you can still integrate Yew with all the usual styling methods.
Finally, we have also to increase the recursion limit if we want our html!
macro to compile. In fact, in order to put more elements in the html!
macro the default limit is too tight.
In src/lib.rs
https://gist.github.com/5b8ff0033944b14505b0de72331c2065
We can run and see the rewards of our efforts!
We will continue in the next installment of this tutorial talking about services.
Originally published at https://dev.to/davidedelpapa/yew-tutorial-02-extending-the-example-55pc