Skip to main content
Version: Next

Handling Events

info

EventEmitter is available since Smartface Native 4.3.5

Migration from Callback to EventEmitter

Within the Native modules, Smartface now adapts with modern EventEmitter methodology to define\&call events prior to callback.

Old Usage:

import Button from "@smartface/native/button";
//...
this.button = new Button();
this.button.onPress = () => {
alert("button pressed");
};

New Usage

import Button from "@smartface/native/button";
//...
this.button = new Button();
this.button.on('press', () => {
alert("button pressed");
});

Advantages

  • While defining Events instead of callbacks, now you can define multiple events and when the touch is done or event is fired, all of the events will be fired.
  • Events can be terminated easily.
info

While the callbacks are deprecated, they will still be usable and will not be removed in any short time. Your current project will work as is.

EventEmitter Usage

Handling events on Smartface is similar to handling events on NodeJS. Functionality and usage is adapted to Smartface ecosystem.

  • Events types are defined as static objects within their respective class
  • Event functions are defined the same as NodeJS eventemitter, with one difference of return values being assigned as the value keyword.
  • Callback methods are also available if you prefer to assign a function directly.

A simple example for Press event in Button:

import Button from "@smartface/native/button";
//...
this.button = new Button();
this.button.on('press', () => {
alert("button pressed");
});

This will create a new listener which listens to the button press. As an alternative, you can also define specific events like this:

import Button from "@smartface/native/button";
//...
this.button = new Button();
this.button.onPress = () => {
alert("button pressed");
};

Within the Native modules, Smartface now adapts with modern EventEmitter methodology to define\&call events prior to callback.

To get more information, click here to access Handling Events documentation below:

Old Usage:

import Button from "@smartface/native/button";
//...
this.button = new Button();
this.button.onPress = () => {
alert("button pressed");
};

New Usage

import Button from "@smartface/native/button";
//...
this.button = new Button();
this.button.on('press', () => {
alert("button pressed");
});

Advantages

  • While defining Events instead of callbacks, now you can define multiple events and when the touch is done or event is fired, all of the events will be fired.
  • Events can be terminated easily.
info

While the callbacks are deprecated, they will still be usable and will not be removed in the short run. Your current project will work as is.

Getting Additional Information Upon Event Call

Some events will provide information upon trigger. To get the provided information, use the parameters in the callback function like shown below:

import Accelerometer from "@smartface/device/accelerometer";
Accelelerometer.on(Accelerometer.Events.Accelerate, (coordinates) => {
console.info(coordinates); // This will print out x, y, z for example.
});

Simulating the Event Call

On some occurrences, the events need to be called manually by code. An example scenario:

  • You have a login button in your login page.
  • You also implement additional button to login to the account, for example at the right of the HeaderBar.

In this scenario, it is advised to stick with DRY(Don't repeat yourself) principle and centralize those actions in a single place. There are a few approaches you can make in this scenario:

  1. Writing a centric function that will be called on both event calls
  2. Writing the action on the event itself and calling the event again instead of repeating the same code. This method is effectively better if the second button is requested to be implemented after the 1st button.
function initButton() {
this.btnLogin.on('press', () => {
const shouldLogin = this.checkFields();
this.showErrorMessages();
shouldLogin && this.login();
});
// Instead of writing these 3 lines again, we call the event itself from another button.
this.btnHeaderBar.on('press', () =>
this.btnLogin.emit('press')
);
}

Unlistening Events

When the event is created, it will be bound to the instance of that component. That component is bound to the page it belongs. Therefore when the page is destroyed, the scope and the underlying events will be released.

However, when there is a need to manually unlisten to events(to not want it to be triggered anymore), you can use the off method in NodeJS EventEmitter or the return value of the on function.

this.unlistener = this.button.on('touch', () =>
alert("button pressed")
);
/** on Function returns the unlistener of the event.
* you can call it directly to unlisten that specific event, like redux subscribe
*/
function onHide() {
//Triggered when the page is exited
this.unlistener(); //Event is removed
}

Alternatively, you can use off method. This requires to also pass the listener function as well. Example:

const buttonListener = () => alert("button pressed");
this.button.on('touch', buttonListener);
/** on Function returns the unlistener of the event.
* you can call it directly to unlisten that specific event, like redux subscribe
*/
function onHide() {
//Triggered when the page is exited
this.button.off('touch', buttonListener); // removes the event
}
p;
info

Singleton pages are not destroyed upon exit, so while exiting a singleton page, you should unlisten the events manually.

Passing the Return Value

On the callback methods, you will occasionally encounter with the methods which requires you to return a value. E.g. the touch events work on callbacks like this:

// Callback method
this.flexLayout.onTouch = (e) => {
//.. do stuff
return true;
};

On EventEmitter approach, this will not work and the return value will be ignored. To pass a return value, you need to assign the value to the value property to a parameter.

// Callback method
this.flexLayout.on('touch', (e) => {
//.. do stuff
e.value = true; // Same as return true on callbacks
});

Miscellaneous

The EventEmitter implementation matches with Node.js 11.13.0 API level.

https://nodejs.org/dist/v11.13.0/docs/api/events.html

To learn more about event handling on NodeJS, refer to the official NodeJS Documentation:

https://nodejs.dev/learn/the-nodejs-event-emitter