ijxkc-rqaaa-aaaal-qcdta-cai.icp0.io Open in urlscan Pro
2a0b:21c0:b002:2:5000:afff:fee6:a836  Public Scan

URL: https://ijxkc-rqaaa-aaaal-qcdta-cai.icp0.io/blogs/codeLab/codelab-01/index.html
Submission: On November 27 via api from US — Scanned from FR

Form analysis 0 forms found in the DOM

Text Content

On IC Academy

How to Work with Result Types
March 15, 2024 - written by Roland BOLE (Instructor)
This is an announcement for a new codeLab 01 that I have recently published on
Github.
All Posts
Code Lab
Releases
42



👋 HAPPY TO SHARE MY NEW CODELAB!

âš¡ How to use the Motoko Result type in a JavaScript frontend application?
In this codeLab you will learn how to use the Motoko Result type to handle
success and error cases in a dictionary application.
github.com

Info

To run this codeLab please follow the instructions in the README file on Github.


WHAT DOES THIS CODELAB CONTAIN?

In this codeLab we pick on aspects from our new course which we are currently
developing. Here, we publish smaller excerpts from it.

The example is about a dictionary service which contains a Motoko backend
service and a SvelteKit frontend application.

The frontend application can search for some entries in the dictionary and if
there is a match the result will be displayed on the frontend.

This is how the frontend looks like

This example focuses on Motoko’s Result variant type.

An example for a Result type could be:

type Result = {
 #ok;
 #err;
};


A value of this type may be one of two possible variants, namely #ok or #err.
These variants are used to indicate either the successful result of a function
or a possible error during the evaluation of a function.

In our example it means, if we find a word to display, the function returns an
Ok type with the dictionary entry.

If the search does not find a corresponding word, then the function should
return an Err type and an appropriate message can be displayed to the user.


LET US DISCUSS THE BACKEND CANISTER BRIEFLY

The backend canister contains two public functions: getWord is a query function
which does not change the state of the canister and, addWord adds a word to the
dictionary, thereby changing the status of the canister.

Both functions have a Result type for the return value which can be imported
from the Motoko base library. The default result expands two types in this
scenario: <Entry, Text>.

The first type is used in the success case (#ok) and the second type in the
error case (#err).

If there is a match then the result type is equal #ok and the record is sent
back to the JavaScript client in our case.

If there is no match the result type is equal #err and this is sent back to the
client with a custom text to display.

Info

The switch expression helps to decide if a record is found or not. The switch
expression is a powerful control flow construct that allows pattern matching on
its input.

public query func getWord(word : Text) : async Result.Result <Entry, Text> {
    let entry = db.get(Text.toLowercase(word));
    switch entry {
      case (null) {
        return #err("Word not found");
      };
      case (?entry) {
        return #ok(entry);
      };
    }
  };


public func addWord(word : Text, description: Text) : async Result.Result <Text, Text> {
  db.put(word, { word = word; description = description; });
  #ok("Word added")
};


Exercise

Feel free to add the frontend application part for the addWord function and also
an error (#err) Result type, if a new entry cannot be stored successfully in the
data store by your own as an exceriece.

The canister stores the dictionary data in a HashMap.

Warning

Note that this store is not stable and you will lose the content if you update
the backend canister.

var db = Map.HashMap<Text, Entry>(0, Text.equal, Text.hash);


Info

In general, a HashMap is also known as a hash table. It is a data structure that
stores key-value pairs. It allows insertion, deletion, and lookup of elements
based on their unique keys.

The data record going to be stored is defined in a type called Entry.

type Entry = {
  word: Text;
  description: Text;
};



LET US DISCUSS THE FRONTEND CANISTER

The relevant code is shown in the +page.svelte file.

Thanks to the automatic type creation these types can also be used for our
TypeScript frontend.

import { backend } from '../stores/ic';
import type { Result} from '../declarations/backend/backend.did.d.ts';
import type { Entry} from '../declarations/backend/backend.did.d.ts';

let search:string = '', error:string ='', entry:Entry | null, result:Result;

const handleOnSubmit = async () => {
  try {

    error = ''; entry = null;

    result = await backend.getWord(search);
    if ('ok' in result) {
      entry = result.ok;
    }
    else {
      error = result.err;
    }
    
    search = '';
  } catch (err) {
      console.error('>> ',err);
  }
};


As you can see, a general import of the backend actor function is used. In this
example it works as a wrapper for the automatically generated ready to use
actor.

Furthermore, the type definitions for the Result and the Entry type are
imported. Also, these types are generated from the dfx generate command which is
executed by a dfx deploy command.

Rember, you can generate these types every time on your own with the command dfx
generate.

The rest is pretty straightforward. You can check if there is an ok property in
the Result object and, if so then there is a match and Sveltes reactivity can be
used to display the data.

Below, there is the snippet for the template code.

<div class="box">
  <form on:submit|preventDefault={handleOnSubmit}>
    <label for="name">Search a word</label>
    <input id="search" alt="Search" type="text" bind:value={search}/>
    <button type="submit">Click Me!</button>
  </form> 
  <div>
    {#if entry}
      <b>{ entry.word }</b>
      <div>{ entry.description}</div>
    {:else }
      <div>{ error }</div>
    {/if}
  </div> 
</div>


> Now you know a little bit more about the Internet Computer, Happy Coding! 🚀

Don’t forget to register to our newsletter and we will keep you updated about
the course development progress.

Newer Post
CodeLab-02: Deployment Automation
Older Post
VERCEL and the Internet Computer
Menu
Where to go?
Home
Courses / Certifications
Consulting
Showcase
Blog
Free Quizzes
Newsletter
YouTube Playlists
About IC Academy
About
Bio
Legal
Imprint
Data Privacy

Join our community on OpenChat, a decentralized chat app governed by the people
for the people. OpenChat meets Slack in a decentralized package.
© 2024 IC Academy - Made with ♥ in Austria
powered by SDG - samlinux development