YEW Megatutorial — Tut 02: Extending the example

Davide Del Papa
6 min readJul 25, 2020
Cover photo by Daria Nepriakhina on Unsplash; the banana, after Cattelan’s exposition, is coming to signify the message of deceptive simplicity.

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.

Add and remove: elementary, Watson!

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.

Generating some random numbers

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!

Finally, our effort’s repaid!

We will continue in the next installment of this tutorial talking about services.

--

--

Davide Del Papa

Landscaper, philosopher of sort, programmer of straws in the wind, and recently…