Hello GUI

Time & Level

Time: ~1 hours | Level: Beginner

Welcome to the first GUI tutorial. So far you have interacted with your zome using curl or hc test, but that's not as nice as having a GUI.

What will you learn

Today you will learn how to interact with a Holochain app using a super simple web page. Using a websocket connection data will be passed to and from a javascript / html web page.

Why it matters

It's likely you will want to write a GUI for your future applications and it's helpful to see how to connect a frontend to your backend zome. This is not the only way to write a GUI for a Holochain app but it should be familiar if you ar e used to web front ends.

Create the HTML page

You will need somewhere for all your GUI code to live. This will be a different piece of software to your Holochain zome code. So choose somewhere outside your Holochain application.

Create a folder for our GUI to live in:

cd holochain/coreconcepts
mkdir gui
cd gui

Create a new file called index.html in your favourite editor. It should live at gui/index.html. Start by adding a simple HTML template to index.html.

Add this modern template:

<!DOCTYPE html>

<html lang="en">
  <head>
    <meta charset="utf-8" />

    <title>Hello GUI</title>
    <meta name="description" content="GUI for a Holochain app" />
  </head>

  <body>
  </body>
</html>

Inside the <body> tag add a button:

  <button type="button">Say Hello</button>

To make things a bit nicer on the eyes you can add the water.css stylesheet.

Add this water.css link inside the <head> tag:

    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/gh/kognise/water.css@latest/dist/dark.min.css"
    />

Run a simple server

Your index.html should now look like:
<!DOCTYPE html>

<html lang="en">
  <head>
    <meta charset="utf-8" />

    <title>Hello GUI</title>
    <meta name="description" content="GUI for a Holochain app" />
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/gh/kognise/water.css@latest/dist/dark.min.css"
    />
  </head>

  <body>
    <button type="button">Say Hello</button>
  </body>
</html>

Enter the nix-shell to make sure you have all the dependencies available:

nix-shell https://holochain.love

Once that is all up and running, you can fire up a simple server:

Run in nix-shell https://holochain.love

python -m SimpleHTTPServer
Or if you use python 3 use this command instead:
python -m http.server

And go have a look in your browser at http://0.0.0.0:8000/. You will see something like this:

hc-web-client

Time to communicate with the app that you built in the previous tutorials. To make this easy you can use the hc-web-client. It's Holochain's JavaScript library that helps you easily setup a WebSocket connection to your app.

Why WebSocket instead of HTTP?

Having a WebSocket connection open allows your app to send messages to your GUI. While we are not doing that today, it's good to get familiar with this process.

To make this process easy we have precompiled a version of the hc-web-client for you.

Download it here, then unzip it and stick it in the root of your GUI directory:

unzip hc-web-client.zip
The files should live here:
gui/hc-web-client/hc-web-client-0.5.1.browser.min.js
gui/hc-web-client/hc-web-client-0.5.1.browser.min.js.map

Once that's done you can easily link to the compiled js file by adding this script tag inside your body tag:

    <script
      type="text/javascript"
      src="hc-web-client/hc-web-client-0.5.1.browser.min.js"
    ></script>

Call the zome function

Now that you have linked the hc-web-client.js library you can make a simple zome call with some vanilla JavaScript.

Add this function inside your <body> tag:

    <script type="text/javascript">

Make a WebSocket connection to Holochain on port 3401:

      var holochain_connection = holochainclient.connect({
        url: 'ws://localhost:3401',
      });

Add a hello() JavaScript function so you can call it from your HTML:

      function hello() {

Wait for Holochain to connect and then make a zome call:

        holochain_connection.then(({callZome, close}) => {

Call the hello_holo zome function in the hello zome running on the test-instance instance:

      callZome('test-instance', 'hello', 'hello_holo')({args: {}})

Log the result in the browser's console:

          .then((result) => console.log(result))
        })
      }

Close the script tag:

    </script>

This hello function will connect to your app through WebSocket on port 3401, call the hello zome function, and print the result to your browser's console.

Let's make your button call this function by adding an onclick event handler.

Add this button inside the <body> tag:

-  <button type="button">Say Hello</button>
+  <button onclick="hello()" type="button">Say Hello</button>

Run your app

Check your index.html:
<!DOCTYPE html>

<html lang="en">
  <head>
    <meta charset="utf-8" />

    <title>Hello GUI</title>
    <meta name="description" content="GUI for a Holochain app" />
    <link
      rel="stylesheet"
      href="https://cdn.jsdelivr.net/gh/kognise/water.css@latest/dist/dark.min.css"
    />
  </head>

  <body>
    <button onclick="hello()" type="button">Say Hello</button>
    <script
      type="text/javascript"
      src="hc-web-client/hc-web-client-0.5.1.browser.min.js"
    ></script>
    <script type="text/javascript">
      var holochain_connection = holochainclient.connect({
        url: 'ws://localhost:3401',
      });
      function hello() {
        holochain_connection.then(({callZome, close}) => {
      callZome('test-instance', 'hello', 'hello_holo')({args: {}})
          .then((result) => console.log(result))
        })
      }
    </script>
  </body>
</html>

To make a call from the GUI, your Holochain app must be running. So open up a new terminal window, navigate to the app you built in the previous tutorials, and enter the nix-shell:

cd holochain/core_concepts/cc_tuts
nix-shell https://holochain.love

Now run your app:

Run in nix-shell https://holochain.love

Package the app:

hc package
Run the server on port 3401:
hc run -p 3401

Make a zome call

In your other terminal window (the one with the GUI code), start the SimpleHTTPServer if it's not still running:

Run in nix-shell https://holochain.love

python -m SimpleHTTPServer

Open up your browser and head to 0.0.0.0:8000 (or refresh the page if it's already open). The page will look the same.

Open you your developer console and click the button. You should see something like this:

I'm using Firefox so this might look a little different depending on your browser

Woohoo! You have made a call to your Holochain app using a GUI.

Render the output

It would be nicer to see the result of the hello_holo call on the page. So let's add a somewhere to show it.

Add the following HTML below the button:

    <div>Response: <span id="output"></span></div>

The id="output" is what we will use to update this element from a JavaScript function.

Add the following lines below you hello function.

Add an show_output function that takes the result:

      function show_output(result) {

Get the element that you'll be inserting the output into:

        var span = document.getElementById('output');

Parse the zome function result as JSON:

        var output = JSON.parse(result);

Set the contents of the element to the zome function result:

        span.textContent = ' ' + output.Ok;
      }

Finally, update the hello function to call your new show_output function instead of console.log().

-            result => console.log(result),
+            result => show_output(result),

Test the output works

Head over to 0.0.0.0:8000 in your web browser (you might need to refresh) and you should see this:

Now press the Say Hello button and you get your response:

Well done! You have a working GUI that can talk to your Holochain app.

Key takeaways

  • You can use regular web front ends to connect to a conductor over websocket.
  • The simplest web front end requires javascript and HTML.
  • Zome functions are callable from the GUI in a similar way to curl.

Learn more

Was this helpful?