# AppScript QML Type

- List of all members, including inherited members

## Properties

- runWhen : string
- running : bool
- script : script

## Signals

- finished(int returnCode)
- started()

## Methods

- exit(int returnCode)
- on(var type, func callback)
- chian once(var type, func callback)
- run()

## Detailed Description

AppScript is a helper component to handle asynchronous sequential workflow. The immediate benefit of using AppScript is the centralisation of code in a place. Instead of placing them within onXXXX code block in several components in several places.

AppScript also manage the life cycle of registered callbacks. You could remove them by a single function. Nothing will leave in memory.

Remarks: AppScript is not a solution for making Store component

Example Code

    AppScript {
        // Run this script if "Pick Image" button is clicked.
        runWhen: ActionTypes.askToPickPhoto

        script: {
            // Step 1. Open file dialog
            dialog.open();

            // Register a set of callbacks as workflow
            // Registered callbacks will be executed once only per script execution
            once(dialog.onAccepted, function() {

                // Step 2. Once user picked an image, launch preview window and ask for confirmation.
                AppActions.navigateTo(imagePreview,
                                      {source: dialog.fileUrl});

            }).then(ActionTypes.pickPhoto, function(message) {
                // The function of then() is same as once() but it won't
                // trigger the callback until once() is triggered.

                // Step 3. Add picked image to store and go back to previous page.

                PhotoStore.add(String(message.url));

                AppActions.navigateBack();

            }); // <-- You may chain then() function again.

            // Condition to terminate the workflow:
            // Force to terminate if dialog is rejected / or navigateBack is dispatched
            // That will remove all the registered callbacks

            once(dialog.onRejected,exit.bind(this,0));

            once(ActionTypes.navigateBack,exit.bind(this,0));
        }
    }

Benefit of using AppScript

- Centralize your workflow code in one place
- Highly integrated with AppDispatcher. The order of callback execution is guaranteed in sequence order.
- Only one script can be executed at a time. Registered callbacks by previous script will be removed before starting.
- exit() will remove all the registered callbacks. No callback leave after termination.

Why not just use Promise?

- 1. You need another library. (e.g QuickPromise)
- 2. You need to set reject condition per callback/promise

Explanation:

Coding in a promise way requires you to handle every reject condition correctly. Otherwise, promise will leave in memory and their behaviour will be unexpected. AppScript::run() / AppScript::exit() clear all the registered callback completely. You can write less code.

## Property Documentation

runWhen : string

This property hold a string of message type. Whatever a dispatched message matched, it will trigger to call run() immediately.

running : bool

This property hold a value to indicate is the script still running. If there has any registered callback leave, it will be considered as running.

script : script

This property holds the script to run.

## Signal Documentation

finished(int returnCode)

This signal is emitted when the script is finished.

Note: The corresponding handler is `onFinished`.

started()

This signal is emitted when the script is started.

Note: The corresponding handler is `onStarted`.

## Method Documentation

exit(int returnCode)

Terminate current executing script by removing all the registered callbacks.

on(var type, func callback)

Register a callback to be triggered when a matched message type is dispatched or a signal is emitted. User should call this function within the script code block.

The callback will be removed on script termination.

chian once(var type, func callback)

Register a callback to be triggered when a matched message type is dispatched or a signal is emitted. It will be triggered once only. User should call this function within the script code block.

The callback will be removed on script termination.

Moreover, this function is chainable:

Example

    AppScript {

        script: {

            once(ActionTypes.askToRemoveSelectedItem, funciton() {

                removeConfirmationDialog.open();

            }).then(removeConfirmationDialog.onAccepted, function() {

                AppActions.removeSelectedItem();

            }); // <-- You may chain then() function again.
        }
    }

The callback in then() will not be registrated immediately. It is deferred until the previouew callback triggered.

run()

Call this function to execute script. If the previous script is still running. AppScript will terminate previous script by removing all the registered callbacks.