--- tags: mstu5013, tutorial, js, riot --- # RIOT Tutorial 06: TAGS ADVANCED For the beginner, one of the fundamental (and challenging) aspects of learning a component framework is understanding how data can be passed around from component to component. Based on different use cases, there are several ways in which you can accomplish this. Examples: - **Parent to Children: Opts** - **Example:** A parent component has some individual state(s) that you want the child to know about. - **Concept:** A single `tweet` object from parent passed into an `<editor>` component and used to fill out the editing form with current tweet data (that will be edited.) - **Parent to Children: Item in Each** - **Example:** A parent component gets a *list* of users, and you want to generate child components based on each user. - **Concept:** Pass each `user` object in _list_ `[user, user, ...]` from parent to generated child. - **Component to Component: Observer (Challenge)** - **Example:** You want some component (not in a parent-child hierarchical relation) to update itself based on the state of another (distant) component. - **Concept:** Changing your _username_ in the `<profile>` component requires the new username data to be passed to various other components not directly connected to each other (e.g. navbar, all your tweets, etc.) This tutorial explains these common cases and how Riot supports these intentions. ## Multi-Component Conceptual Example In RIOT, tags are simply objects with some default RIOT properties and methods (functions associated with an object,) as well as custom properties and methods we define in each tag. <!-- Doesn't directly lead to something they need in order to learn the data passing... So far, we have seen and practiced how to: - Create new instances of a tag by nesting tags and how those tags have a parent-child relationship. - Use the `ref` property to create a reference that will be used to grab the data from the user. - Utilize *conditional attributes* (e.g. `if={}`, `show={}` & `hide={}`) inside of tags to display different elements and components, based on the state of the tag - Use the `each` attribute to loop over an array or array of objects. - Add *event handlers* (e.g. `onclick`, `onmouseover`, `oninput`, etc.) to our HTML tags to trigger callback functions in response to the user interactions. - Listen to *lifecycle events* (e.g. `mount`, `update`, `unmount`, etc.) and fire callback functions. --> In a sophisticated (multi-component) app, how is data being passed around and used? Let's take a look at an App that we use daily: > GMAIL Let's say we want to create an application *like* GMAIL. As you can see bellow, we are going to have the user's information repeated here and there. **Example:** ![](https://i.imgur.com/A9U0mUi.png =500x400) **Data Concept:** ```jsx <app> // this.user = { username: "Anabel", email: "aaa@gmail.com", ... } <navbar> // needs `user` to create "circle-A" based on first character <user-dropdown> // needs `user` to print full name, email, other info <account-item> // needs `user` to print name and email // maybe other `user` objects that represent other accounts </account-item> </user-dropdown> </navbar> <email-browser></email-browser> <editor> // needs `user` data to autofill "From" section </editor> </app> ``` Imagine that you are developing the GMAIL App with RIOT, so we will create a separate component for email *editor*, the *navbar*, and the *dropdown menu*. Imagine having to create an user object in each of these tags. Wouldn't it be nice to create the `user object` in only one place and be able to pass the data around? This optimizes our application since it would make our code more concise and readable, and improve the user experience since the user wouldn't have to manually type his email address or name every time he sends an email or to open the GMAIL account everytime he wants to know in which GMAIL account he's at. To accomplish this, RIOT offers a few distinctive ways of passing data around. Remember, data is just that -- data. It can be as simple as passing a single _String_, _Number_, _Boolean_, or more complex data structures like _Object_, _Array_, and even things like _Functions_. Javascript doesn't care what you pass along, as long as the data you pass is referenced correctly. ## Passing Data from Parent to Child: `opts` (options) Riot tags are instantiated as JS objects. We can add new properties to the tag object. We have already been doing this. We have been using custom properties as ways to set _state_ to our tags. For example: ```jsx <todo> this.done = true; </todo> ``` `this` usually points to the tag context. Therefore, by assigning a new property to the tag: ```javascript this.newObj = { task: "Feed cat" }; ``` We assign `newObj` as a new property of the tag object set to the value of the object data `{ task: "Feed cat" }` So far, we've done this explicitly by setting state within our code like above. And we see the property being added directly to the tag object itself. Example: ![](https://i.imgur.com/JkdXtRm.png) Notice how the property `username` is attached directly to the tag object, along with other custom properties like the `sayHello` function. But when we pass data from one tag to another, that is - from parent to child, we often use a very special property that is available to us through Riot. What we'll be focusing on next, is the property `opts` (options) as illustrated above. ### Opts You'll notice above that `this.opts` is set to an empty object `{}`. In any Riot tag, by running `console.log(this)` you will see the `opts` property set to an object. > `opts` is a special property that is provided in *all* Riot tags by default. You can think of `opts` as a _pocket_ for data. You can pass data from a parent component to a child component, and that data ends up in the `opts` object (pocket.) _You can decide_ how data will be referenced within the `opts` object. The following diagram describes the conceptual linkages between _tags_, _attributes_, and _opts_. Pay particular attention to how the _attributes_ are named, and how they are referenced in the child tags via _opts_. **Make sure you click the large version (and zoom in) to be able to read it.** OPTS DATA: [Click here to see large version.](https://i.imgur.com/RizLXZk) ![](https://i.imgur.com/RizLXZk.png) In the above example, the parent `<app>` tag has `this.user` and `this.language` set. In the `<app>` tag context, `this.opts` is equal to `{}` (no special data in particular, empty object.) We pass the `user` and `language` data into two children tags `<navbar>` and `<page>`. We pass them in using attributes we defined. Notice how I use different attribute names for the same data, to emphasize how I expect to find them in the child tag's `opts` object. - `<navbar user={ ... } lang={ ... }>` - Expect to find `opts` in `<navbar>` as follows: ```javascript // Navbar tag this.opts = { user: { name: "Alpha", age: 21 }, lang: "JPN" } ``` - `<page me={ ... } lingo={ ... }>` - Expect to find `opts` in `<page>` as follows: ```javascript // Page tag this.opts = { me: { name: "Alpha", age: 21 }, lingo: "JPN" } ``` **Another Example:** ```jsx= <tag-a> // Definition of the user property and its value. <tag-c username="John Doe"></tag-c> </tag-a> ``` You'll notice that in `<tag-c>` we have an _attribute_ called `username`. This is an attribute that we created and could have been named anything. The value `"John Doe"` is the data (String) that is going to be passed into `<tag-c>`. ![](https://i.imgur.com/LxWIIe7.png =390x120) When `<tag-c>` is instantiated, we will find this data within the `opts` object. `username` will become a property of the `opts` object inside `<tag-c>`. We can pass any data into `opts` in this way (e.g. _String_, _Number_, _Object_, _Array_, etc.) Within `<tag-c>`, we can access this _passed_ data by referencing it via `opts`. **Example: Inside `<tag-c>`** ```jsx= <tag-c> <h2>{ opts.username }</h2> // assumes this.opts.username // becomes <h2>John Doe</h2> </tag-c> ``` Thus, using `opts` is an easy way to pass data from the parent into the child tag. You can pass multiple data via multiple attributes in this way. ### Attribute naming: `kebab-case` vs. `camel-case` **tweet.tag** ```jsx <tweet> // Pass two pieces of data to editor `opts` <editor edit-tweet={ tweet } username={ me }></editor> this.tweet = { author: "Adam Smith", content: "Bitcoin is the bomb.", imageURL: "https://bitcoin.org/img/icons/logotop.svg" }; this.me = "The Original Adam"; </tweet> ``` **editor.tag** ```jsx <editor> // Hello The Original Adam <h2>EDITOR: Hello { opts.username }!</h2> // Adam Smith says Bitcoin is the bomb. <p>{ opts.editTweet.author } says { opts.editTweet.content }</p> // Bitcoin logo image <img src={ opts.editTweet.imageURL }> </editor> ``` In the example above, notice that we created an attribute `edit-tweet` and we passed in the entire `tweet` data object. An important thing to note is that in HTML (and Riot) attributes use `kebab-case`. But within `opts`, the attribute name is converted to the Javascript convention `camelCase`. - `edit-tweet` _attribute_, becomes `editTweet` _property_ in `opts`. This is one of the common **gotchas** in Riot. > Name your _attributes_ using `kebab-case` and expect `camelCase` in _opts_. `kebab-case` is standard convention for HTML attributes. As a matter of fact, there are other ways you can goof this up. ```jsx <tweet> // Notice: I am using camelCase for my attribute, I shouldn't do this. <editor editTweet={ tweet } ... ></editor> ... </tweet> ``` Did you expect to find `editTweet` inside your `opts` object? You won't find it. And, you'll probably get errors. HTML/JS rules will convert the `camelCase` attribute `editTweet` to an all lowercase property `edittweet`. - `editTweet` _attribute_, becomes lowercase `edittweet` _property_ in `opts`. You might think this is weird behavior. But it's based on standrad HTML/JS rules. So as a matter of consistency and convention: > Name your _attributes_ using `kebab-case` and expect `camelCase` in _opts_. It's up to you how you pass data from parent to child via `opts`. Usually, we tend to send entire _groups_ of data as objects but we only use specific aspects of the object data. If you want to send in only the data to be used, you're free to do so. The next example is completely _legit_ although it starts to get a little wordy in the template. **my-pet.tag** ```jsx= // PARENT TAG <my-pet> <h2>Pet ID card</h2> // CHILD TAG <id-card pet-name={ myPet.name } pet-breed={ myPet.breed } pet-color={ myPet.color } pet-happiness={ myPet.happiness }></id-card> <script> this.myPet = { name: "Oscar", breed: "poodle", gender: "male", age: "2 years old", color: "brown", happiness: "85%" } </script> </my-pet> ``` **id-card.tag** ```jsx= // CHILD TAG <id-card> <table> <thead> <tr> <th>{ myPet.name }'s breed</th> <th>{ myPet.name }'s color</th> <th>{ myPet.name }'s happiness level</th> </tr> </thead> <tbody> <tr> <td>{ myPet.breed }</td> <td>{ myPet.color }</td> <td>{ myPet.happiness }</td> </tr> </tbody> </table> <script> // Initializing the object and setting default values this.myPet = { name: "unknown", breed: "unknown", color: "unknown", happiness: "unknown" } // Set values of myPet object from `opts` data received from parent this.on('update', function(){ this.myPet = { name: this.opts.petName, breed: this.opts.petBreed, color: this.opts.petColor, happiness: this.opts.petHappiness }; }); </script> </id-card> ``` In the above example, we do something a bit different. We have a lifecycle listener listening for the `update` event. Every time `<id-card>` updates, it will set `this` instance of `myPet` to the `opts` data passed in from `<my-pet>` tag. In our template portion, we reference the `myPet` instead of `opts`. This is sometimes preferrable as typing `opts` a lot can clutter the template space. ## Passing Data through `each={ list }` We can also use each to pass data from parent to child tags. We've already been doing this but perhaps, without a deeper understanding of what is being passed and how. With `each` we are usually interested in passing item data from an array, into a child tag. > For each _item_ in the _array_, create a new tag and inject the _item_ data into it. **Conceptual Example** ```jsx <app> // Loop through `this.tweets` // Set the object data properties of that iteration to child <tweet each={ tweets }></tweet> this.tweets = [ { msg:"Hello" }, { msg:"Konnichiwa" }, { msg:"Hola" } ]; </app> <tweet> // Interpolate `this.msg` into paragraph <p>{ msg }</p> </tweet> ``` Maybe this is not that obvious but each time that RIOT loops over an array with the `each={}` attribute, it's creating a new tag instance. An instance is like its own little micro-universe. In the above example, this creates 3 tweet instance objects, each with their own unique `this.tweet` data. Every time you create a new instance, that component -- the JS Object has its own unique context. To get a diagramatic view of how data is passed through `each={ list }` pattern, see the image below. **Make sure you click the large version (and zoom in) to be able to read it.** EACH DATA: [Click here to see large version.](https://i.imgur.com/eMh2ZI1) ![](https://i.imgur.com/eMh2ZI1.png) In the above example, the most important concepts are the following: 1. Riot loops through the `this.tweets` array as directed by the `each` attribute. 2. For each data object in `this.tweets` Riot instantiates a new `<tweet>` tag instance. 3. Riot _directly_ attaches the data object properties as properties to the child `<tweet>` component. 4. Riot repeats this until all data objects are processed. In the above example, we pass data via `each` to the `<tweet>` component which we defined. However, it can often be less obvious that we are dealing with Riot tag instances. See the following similar code. ```jsx <app> <ul> <li each={ tweets }> // Creates a Riot tag instance <p>{ msg }</p> // Child tag context </li> <ul> this.tweets = [ { msg:"Hello" }, { msg:"Konnichiwa" }, { msg:"Hola" } ]; </app> ``` Compared to the prior example, this one does not utilize a custom component `<tweet>` but rather uses a standard `<li>` to loop on. However, because we are using `each` -- every `<li>` created by this operation becomes a Riot JS object (tag). Everything between the `<li> ... </li>` will be treated in the context of a child tag. When we use the `each={ list }` to iterate through a list of objects, Riot takes each object, and sets the properties of that object as properties of the child tag instance. Child tags will have all the same regular default properties that a Riot tag will have (e.g. `opts`, `refs`, `parent`, etc.) Furthermore, any state properties and methods set in the parent will also be passed onto as child properties. Therefore, every time we use the `each={ list }` looping pattern, RIOT is creating new tag instance per each item in the array and nesting them in the parent tag. However, the tag that contains the `each={ ... }` atrribute does not belong to the child context but to the parent. ```jsx= <navbar> <div> <a each={ menu } href="#{ menuItem }">{ item.toUpperCase() }</a> </div> <script> this.menu = [ { menuItem: 'home'}, { menuItem: 'news'}, { menuItem: 'contact'}, { menuItem: 'about'} ]; </script> </navbar> ``` - **Line 4:** Here we are creating a new tag instance per item. Since our array `menu` has 4 objects, RIOT will create 4 `<a>` tags for us, therefore it will look something like this: ```jsx= <navbar> <div> // ORIGINAL LOOP TEMPLATE // <a each={menu} href="#{item}">{ item.toUpperCase() }</a> // BECOMES TAG INSTANCES (OUTPUT) <a href="#/home">HOME</a> // CHILD tag 1 <a href="#/news">NEWS</a> // CHILD tag 2 <a href="#/contact">CONTACT</a> // CHILD tag 3 <a href="#/about">ABOUT</a> // CHILD tag 4 </div> </navbar> ``` - **Line 8-11:** Each `<a>` element is a sibling to each other, and all of them are instances of the `<a>` tag template containing the `each={}` attribute. ## Passing Data through `each={ x in list }` There is an alternate version of `each` syntax which changes how the passed data is referenced in the child tag. That is, `each={ x in list }`. `x` represents the data item in the array list that you are looping through. It can be named anything, and is helpful if you name it something that represents a data item in the list. > For each _thing_ in _list_, create a tag instance and pass that _thing_ in. **Examples:** ```jsx <tweet each={ item in tweets }></tweet> // Instantiates 2 <tweet> tags this.tweets = [ { user:"Alpha", text:"Hello" }, // 1st `item` is {user:"Alpha", text:"Hello"} { user:"Bravo", text:"Bye"} // 2nd `item` is {user:"Bravo", text:"Bye"} ]; <word each={ word in words }></word> // Instantiates 3 <word> tags this.words = [ "Alpha", // 1st `word` is Alpha "Bravo", // 2nd `word` is Bravo "Charlie" // 3rd `word` is Charlie ]; <li each={ n in primeList }></li> // Instantiates 6 <li> tags this.primeList = [2,3,5,7,11,13]; // 1st `n` is 2 // 2nd `n` is 3 // 3rd `n` is 5 // ... ``` Unlike the simple `each={ list }` pattern, the `each={ x in list }` pattern will set a child property named `x` and set that to the data passed in. So in the example above, for each `<tweet>` child component, we can expect a property named `item` with the appropriate data _Object_ set to it. In each `<word>` tag, we'll find a property named `word` with the appropriate _String_ set to it. And finally, in our `<li>` tag, we'll find a property named `n` set to the matching prime _Number_. This pattern is more specific. Unlike the simple `each={ list }`, _ONLY_ the data passed and referenced via `x` reference will be inherited by the child tags. For a diagramatic explanation, see the image below: **Make sure you click the large version (and zoom in) to be able to read it.** X in EACH DATA: [Click here to see large version.](https://i.imgur.com/1sVnuJm) ![](https://i.imgur.com/1sVnuJm.png) In the above example, pay close attention to: - Each data in the list and how it becomes a child tag instance. - The `x` in `x in list` pattern and how that is referenced in the child tag. - If the data passed in is an object, how the specific data properties are referenced within the child tag context. - These are color coded for a reason. :::info **NOTE:** To be honest, this stuff isn't _difficult_ per se. But _it can be very confusing_ as there are multiple ways to pass data into tags. Based on the pattern used, the resulting _how to reference said data_ changes. In order to get comfortable, I **highly recommend** that you create simple tags with your own arbitrary data (keep it simple) and try the `opts` pattern, `each={ list }` pattern, and the `each={ x in list }` pattern. `console.log(this)` when possible in your tags to explore what a Riot tag object and its properties look like. Browse the `opts` as well as other properties and match it to your passed data so you can see the relations. This should make it easier for you to find the data you need. Even if you don't remember exactly where your data is, if you understand where to look -- that will help tremendously. ::: ### Adding/Removing data from looped Arrays - If you want to add a new pin to your Pinterest Board... - If you want to remove a tweet to your tweet list (stupidly drunk posting...) What do you need? What do you do? Remember that in Riot, our application should react to the data. > Change in _state_ should drive the application update and refresh. In the examples above we often work with _array lists_ of data from which we generate child tags of each specific piece of data. So when we add or remove things we really want to target the original data in the original list. That is: > Add or remove data directly to/from the _array list_ and `update` Our _array list_ usually resides hierarchically in a more _parent_ tag. If we can change the _state_ of the original list and `update` an upstream (parent, grand-parent, etc.) tag, Riot will then `update` all child tags downstream to reflect the original and most up to date list and items within. #### Adding and Removing The `each={}` pattern loops through the original data in an array list. Thus, our aim is to target the original array list and data. ```jsx= <navbar> // PARENT context start <span class="myLink" each={ menu }> // (still) PARENT context <a href="#{ item }"> // CHILD context start <span>{ menuItem.toUpperCase() }</span> <span onclick={ removeItem }>🗑</span> </a> // CHILD context end </span> // (back to) PARENT context // THESE are both in the PARENT context <input type="text" value="" ref="newItem"> <button onclick={ addItem }>Add Item</button> this.newItem; this.menu = [ { menuItem: 'home' }, { menuItem: 'news' }, { menuItem: 'contact' }, { menuItem: 'about' } ]; addItem(event){ this.newItem = { menuItem: this.refs.newItem.value }; this.menu.push(this.newItem); // RESET THE INPUT this.refs.newItem.value = ""; this.refs.newItem.focus(); } // Note that in RIOT, `event.item` is a special property to the event // object. It is available in child tags created through `each` // event.item refers to data passed into the child through a loop removeItem(event){ var toBeRemoved = event.item; var index = this.menu.indexOf(toBeRemoved); this.menu.splice(index, 1); } <style> .myLink { margin-right: 1em; cursor: pointer } </style> </navbar> ``` - **ADDING DATA** - **Line 14, 15:** User inputs a new menu item and pushes "Add Item" button. - **Line 26:** `addItem()` is called. - **Line 27-29:** A menu item object (data) is created `{ menuItem: "Some user input" }` - **Line 31:** The object (data) is pushed to the original array. - `this.menu.push(this.newItem)` - **Line 34 & 35:** Input is reset and focus set back on input. - **REMOVING DATA** - **Line 7:** User clicks on trash can. - Each trash can is associated with _one_ instance of a menu item. - **Line 42:** `removeItem()` is called. - **Line 43:** Using the special `event.item` property of the event object, we reference the data that was passed into that child context. - Example: `event.item = { menuItem: 'home'}` if the trashcan in the 'home' component is clicked. - **Line 44:** We find the index of the data we want to trash within the original array list. - `this.menu.indexOf(data)` looks for `data` within `this.menu` array and returns the index number. - **Line 45:** We remove 1 item from `this.menu` starting at `index` - `this.menu.splice(index, numItemsToRemove)` - `Array.splice()` will slide remaining items over when items are spliced out. - **Line 46:** `update` is automatically called. - Notice that the `removeItem` function is declared in the parent context. - `update` occurs IN the parent context. All child tags are refreshed based on the new (shorter) array list. - Results in the list looking like one item was removed. ## Passing Data from Component to Component: Observables :::info **NYC Emergency Services:** Imagine everyone in our class was either NYC Police (NYPD), Fire Department (FD), or Emergency Medical Technicians (EMT). Godzilla attacks NYC and you can imagine, everyone is buzzing around and in need to coordinate some actions. It would be very difficult if each member had to connect to the right department and right people individually to communicate and coordinate things. So what are we supposed to do? **Use a centralized _DISPATCH_ service.** A single, centralized, dispatch service that _listens_ to the radio waves for various _events_ and can _call_ on various specific teams to do specific things is a much more organized way to do things. Since everything runs through _DISPATCH_ we know that all our messages will be _aggregated_ to a centralized location, and _broadcast_ out to all parties listening.<br><br> > **FD:** Hello dispatch, code `fire:zone8`, known injured `7`. > **DISPATCH:** Roger FD. All units listening for code `fire:zone8`. `7` known injured -- please respond. > **EMT:** I hear you dispatch, code `fire:zone8` -- readying `7` medivacs. > **NYPD:** I hear you dispatch, code `fire:zone8` -- sending patrol units. Observables, as we will explain -- are much like this. Let a single, central, observer do the work of relaying events and passing relevant data. ::: Sometimes, we want to pass data from one component to another, but they don't have a clean parent-child hierarchy. Like our NYC example, sometimes it's not so clear-cut how our components can easily communicate. Imagine the following: **Not Convenient, distant relatives:** ```jsx <sibling-A> <inner-A> <profile> this.username = "Alpha"; </profile> </inner-A> </sibling-A> <sibling-B> <inner-B> <p>Hi { username }</p> </inner-B> </sibling-B> ``` Suppose we had original data in `<profile>` that is also needed `<inner-B>`. There is no real easy way (so far) to communicate any _state_ changes occuring in `<profile>` to `<inner-B>`. Example: I change my username. In cases like this, we can use something called _Observables_, also known as the observer pattern, or event aggregation. The way this works is we create a special object that is available _anywhere_ in our application. Often times a global object. ```jsx= <html> <body> <app></app> ... <script> // Creates a globally accessible, observable object. var observable = riot.observable(); riot.mount('*'); </script> </body> </html> ``` Since it's declared at the global level, we can refer to it via the variable name `observable` in any tag. You can name it anything you want, but `observable` is as good as any. `observable` objects can do two things. - Listen for custom events and execute a handler. - `observable.on(event, callback)` -- Run callback anytime event is triggered. - `observable.one(event, callback)` -- Only once, run callback when event is triggered. - Trigger an event. - `observable.trigger(event, optionalData)` Those are pretty much the only functions an observable object has. See Diagram for concept of how observers and event aggregation work: **Make sure you click the large version (and zoom in) to be able to read it.** Observable: [Click here to see large version.](https://i.imgur.com/nlurU2E) ![](https://i.imgur.com/nlurU2E.png) The gist of the above diagram is as follows: 1. An _observer_ or _event aggregation_ object is created: `observable`. - `observable` is accessible globally, all tags can refer to it. - This is basically our emergency _dispatch_ service. 2. `observable` does all the work. - It _triggers_ custom events. - It _listens_ for custom events. - It _handles_ custom events. 3. Data can be passed through the `observable` - `observable.trigger(event, data)` - `observable.on(event, function(data) { ... })` - Note: The context of the callback function with `observable.on()` is NOT the tag `this`. `this` refers to the `observable` object. Therefore, we can _connect_ it to our tag context via a variable we named `that`. 4. `var that = this;` (Set the variable `that` to `this` tag.) To go into more detail, in order to listen for events, we use the `observable` `on()` and/or `one()` functions. ```jsx // PATTERN: // observable.on(event, callback function) // Each time event is triggered, call the callback function. observable.on('eventName', function(dataIn){ // handler code to be executed }) // VS. // Only once, call the callback function when event is triggered, // then stop listening. observable.one('eventName', function(dataIn){ // handler code to be executed }) ``` To trigger an event we use the `observable` `trigger()` function. ```jsx // PATTERN: // observable.trigger(event, data) var dataOut = { injured: 7, zone: 8, special: "Godzilla" }; // `dataOut` can be anything observable.trigger('eventName', dataOut); ``` Any tag that is connected to the `observable` listening for the `eventName` will indirectly be able to interface with the event and passed data. In the following example we have a `<tag-a>` that will print a random number. However, notice that it starts with no _state_ data for `this.myNumber`. It also lacks a direct interface (e.g. button) that will call a function to generate a random number. However, it IS listening for an event named `"magicNumber"`. ```jsx <html> ... <script> var observable = riot.observable(); ... </script> </html> <tag-a> <pre>My number is { myNumber }</pre> var that = this; // observable listening for "magicNumber" event. observable.on('magicNumber', function(){ that.myNumber = Math.floor(Math.random() * 100); that.update(); }); </tag-a> ``` If `magicNumber` event is triggered through `observable`, the handler function will generate an integer between 0 and 99 and set it to `<tag-a>`'s `this.myNumber`. Note that inside the _callback_ we refer to the `<tag-a>` context via `that` instead of `this`. Remember that in _observable callbacks_ `this` refers to the `observable` object, not the tag. Hence, we work around this by setting the variable `that` (above) to `this`. `var that = this;` In the context of that code, `this` _IS_ still in the context of the tag. Therefore, we can use the reference `that` anywhere to refer to the tag. So let's trigger the event. ```jsx= <tag-b> <button onclick={ getNumber }>Tag-B</button> // Triggers the 'magicNumber' event this.getNumber = function(e){ observable.trigger('magicNumber'); } </tag-b> ``` In `<tag-b>` which could be anywhere distant in the application from `<tag-a>` the button is clicked. `getNumber()` is called. And then the `observable` object `trigger()` function is called with the `magicNumber` event. Since `<tag-a>` has `observable` listening for this particular event, when the event is triggered -- the handler is called and we can work with it to set the tag `that.myNumber` to a random integer, and `update()` the tag. The global `observable` object, connects distant tags together. It relays events and deals with event handling. --- :::info ## About the keyword `this` We can kind of get away with a loose understanding of `this` keyword. However, it's a rather important concept to understand in Javascript and if you can get a hold of it, it will help you greatly. Remember that `this` is a special Javascript keyword. When functions are called in Javascript, the `this` keyword inside a function refers to the object (context) from which the function was called. **Example:** ```javascript= function printThis() { console.log(this); } printThis(); // Window Object (global) var car = { vroom: function() { console.log(this); } }; car.vroom(); // car Object ``` In the above example, `printThis` function is called in the context of the global object Window. Thus, `this` points to the window and we see that printed in the console. The method `vroom` is a function that is called from the context of the `car` object. Thus, `this` points to the `car` object and we see that in the console log when we call `car.vroom()`. ```javascript= function globalThis() { console.log(this); } var x = { thisIsAlpha: globalThis, thisIsBravo: function() { console.log(this); }, thisIsCharlie: function() { console.log(this); globalThis(); }, thisIsDelta: function() { globalThis.bind(this).call(); } }; globalThis(); // prints Global Window Object x.thisIsAlpha(); // prints x Object x.thisIsBravo(); // prints x Object x.thisIsCharlie(); // prints x Object, Global Window Object x.thisIsDelta(); // prints x Object ``` - `globalThis()` Called from the global window object context. - `x.thisIsAlpha()` Points to `globalThis` but is called from the `x` object context. - `x.thisIsBravo()` Called from the `x` object context. - `x.thisIsCharlie()` Is called from the `x` object context. - But then calls `globalThis()` from the global window object context. - `x.thisIsDelta()` Called from `x` object context. - `globalThis` is bound to the `x` object context - then `call()` called, making `this` inside the `globalThis` point to `x` object. :::