Web Component

The fastn allows for the integration of custom web components created using JavaScript (or other languages that compile to JavaScript).

Like component, web-components are independent and reusable bits of code and they have arguments.

Create Your Web Component

A web-component in fastn can be created using web-component keyword. Here’s an example of how to integrate a web component created using the standard Web Components API.
web-component.js
class HelloWorld extends HTMLElement {
  constructor() {
    super();
    const shadow = this.attachShadow({ mode: 'open' });
    const div = document.createElement('div');
    div.classList.add('hello-world');
    div.textContent = 'Hello World!';
    div.style.color = 'orange';
    div.style.borderWidth = '1px';
    div.style.borderColor = 'yellow';
    div.style.borderStyle = 'dashed';
    div.style.padding = '10px';
    shadow.appendChild(div);
  }
}

customElements.define('hello-world', HelloWorld);
Lang:
js
index.ftd
;; component call
-- hello-world:

;; Create a web component
-- web-component hello-world:
js: web-component.js

-- end: word-count
Lang:
ftd
In above code we have created a web component hello-world in web-component.js. Then, we’ve included the web component in fastn using the web-component , and used it in the fastn component tree using the hello-world element. used it in index.ftd.
Output

Data Across JS and fastn Worlds

When working with web components, it is possible to share the data between the JS and fastn worlds, which can be managed and updated efficiently, reflecting the changes in both worlds.

fastn provides a function component_data which exposes data arguments, passed from fastn world, and it’s access methods. There are three access methods provided by fastn, against an argument:

  • get: To get the value of the variable in fastn. This method is present for both mutable and immutable variables.
  • set: To set the value of the variable in fastn. The value set using this method will reflect it’s changes in fastn world. This method is present for mutable variables only.
  • on-change: To listen for any change in variable value in fastn world. This method is present for both mutable and immutable variables.
Let’s look at these in more detail.

A Web Component With Argument

Lets create a web component that takes an argument.
index.ftd
-- web-component num-to-words:
caption integer num:
js: web-component.js
Lang:
ftd
web-component.js
class NumToWords extends HTMLElement {
    constructor() {
        super();
        // `window.ftd.component_data` exposes the data
        // arguments passed from `ftd` world.
        let data = window.ftd.component_data(this);

        // `get()` method gives the value of the argument
        // passed.
        let num = data.num.get();

        const shadow = this.attachShadow({ mode: 'open' });
        const div = document.createElement('div');
        div.textContent = numberToWords(num);
        div.style.color = 'orange';
        div.style.borderWidth = '1px';
        div.style.borderColor = 'yellow';
        div.style.borderStyle = 'dashed';
        div.style.padding = '10px';
        shadow.appendChild(div);
    }
}

customElements.define('num-to-words', NumToWords);


function numberToWords(num) {
// some code here
}
Lang:
js
Now lets call this component and pass a data.
Input
-- num-to-words: 19
Lang:
ftd
Output
Output
We have seen how data can be passed from fastn and consumed by js.

Working with mutable data

Now let’s mutate the data and correspondingly change the output from js world.
index.ftd
-- integer $num: 0

-- ftd.integer: $num

-- ftd.text: I increment the `num`
$on-click$: $ftd.increment($a = $num)

-- num-to-words: $num
Lang:
ftd
class NumToWords extends HTMLElement {
    constructor() {
        super();
        let data = window.ftd.component_data(this);
        let num = data.num.get();

        const shadow = this.attachShadow({ mode: 'open' });
        const div = document.createElement('div');
        div.textContent = numberToWords(num);
        div.style.color = 'orange';
        div.style.borderWidth = '1px';
        div.style.borderColor = 'yellow';
        div.style.borderStyle = 'dashed';
        div.style.padding = '10px';

        // `on_change()` method listen to any changes done
        // against the argument value in ftd.
        data.num.on_change(function () {
            const changed_value = data.num.get();
            div.textContent = numberToWords(changed_value);
        })

        shadow.appendChild(div);
    }
}
Lang:
ftd
In above example, we have added a mutable variable num, whose value can be changed by an event in fastn. This changes is then listen using on-change function which do the necessary changes in js world.
Output
0
I increment the num
Now let mutate the data from js world too.
web-component.js
class NumToWords extends HTMLElement {
    constructor() {
        super();
        let data = window.ftd.component_data(this);
        let num = data.num.get();

        const shadow = this.attachShadow({ mode: 'open' });
        const div = document.createElement('div');
        div.textContent = numberToWords(num);
        div.style.color = 'orange';
        div.style.borderWidth = '1px';
        div.style.borderColor = 'yellow';
        div.style.borderStyle = 'dashed';
        div.style.cursor = 'pointer';
        div.style.padding = '10px';

        div.onclick = function (_) {
            let current_num = data.num.get();
            current_num -= 1;
            div.textContent = numberToWords(current_num);
            data.num.set(current_num);
        }

        data.num.on_change(function () {
            const changed_value = data.num.get();
            div.textContent = numberToWords(changed_value);
        });

        shadow.appendChild(div);
    }
}
Lang:
ftd
index.ftd
-- num-to-words:
$num: $num

-- web-component num-to-words:
caption integer $num:
js: web-component.js
Lang:
ftd
In the above code as you can see that we are passing the mutable reference of num variable to the web-component num-to-words which then decrements by it.
Output
0
I increment the num

Support fastn!

Enjoying fastn? Please consider giving us a star ⭐️ on GitHub to show your support!

Getting Help

Have a question or need help?

Visit our GitHub Q&A discussion to get answers and subscribe to it to stay tuned.

Join our Discord channel and share your thoughts, suggestion, question etc.

Connect with our community!

Found an issue?

If you find some issue, please visit our GitHub issues to tell us about it.

Join us

We welcome you to join our Discord community today.

We are trying to create the language for human beings and we do not believe it would be possible without your support. We would love to hear from you.
Copyright © 2023 - FifthTry.com