If you find any errors, typos or have general feedback, select the text and click CTRL+ALT+ENTER.

Creating a new JavaScript asset

To create a new custom JavaScript file, go to: CREATE NEW > JavaScript, set the Dependency Manager options (Enabled, Global, Use shim), and then select the predefined JavaScript file from the drop-down (Angular module, Angular service, Angular factory, Angular directive, Angular filter, or External lib).

This will set the corresponding Dependency Manager resource type, and the template of the file which you want to create.

Angular service, Angular filter, Angular factory and Angular directive types correspond to the Angular resource in the Dependency Manager.

More information on the Dependency Manager options can be found here.

You can read more on creating the corresponding modules in the official AngularJS documentation.

When creating a new JavaScript of Angular module and External Lib type, it is recommended that you leave the Use shim checkbox unchecked to create an AMD (Asynchronous module definition) module.

This is due to the slight difference between developing an AMD or non-AMD module. The only distinction is that AMD modules have the define wrapping, while non AMD modules do not.

AMD modules are also easier to program. In an AMD module, all the dependencies and returned values can be defined inside the module, but data in a non-AMD module must be defined in the Dependency Manager.

For example, you can simply insert the code of a 3rd party module or library into the define function callback, and then set the module dependencies in the array of the first argument of the define function. If you insert the code of a 3rd party library/module without define wrapping, you will have to set the module dependencies in the Dependency Manager. You can find this under App settings > Resources in your project: Shim > Deps.

Modules are connected by name, therefore the module and the JavaScript file names must match. Also, only one module can be created within one file.

Services

AngularJS services are substitutable objects that are wired together using a dependency injection. You can use services to organise and share code across your app. There are two popular kind of services:

  • service – when injecting service by calling Apperyio.get('name')  you will be provided with an instance of the function. The retrieved result will equal to new FunctionYouPassedToService().
  • factory – when injecting factory, you will be provided with the value that is returned by invoking the function reference passed to module.factory.

See more details at Stack Overflow discussion.

In Appery.io you can create custom services by performing CREATE NEW > JavaScript and choosing Angular service in Type drop-down. You will get a template for creating chosen AngularJS resource:

For those, who familiar with AngularJS, this template could look wired. This is because Appery.io uses AMD mechanism and RequireJS to asynchronously load resources on demand.

Read this blog post about AngularJS and RequireJS in Appery.io.

Creating custom service

In purpose to learn more on how to write custom AngularJS services in Appery.io, lets look at the following example:

Example will show how to create service which should sum some numbers in asynchronously way with following conditions:

  1. Service method should return promise object.
  2. If result of calculation is more than 100, promise should be rejected, otherwise promise should be resolved as success.
  3. In both cases, calculation result should be sent into callback.

Example will be shown in two forms – as service and as factory.

Service

Example uses $timeout function to implement asynchronous approach. AngularJS $q service will provide promise object. Lets add those dependencies and save them in object:

While AngularJS service is used, all the dependencies should be stored inside the object for future use. This is because all object methods should be added to prototype of a service function.

Custom methods should be added to a service via the prototype property. Adding a  sum method will looks like this:

When AngularJS service is executed via the dependency manager, AngularJS always call the service-function (in our case Func) as new Func() to create a new instance of an object. That’s why prototype is used here.

You should remember, that JavaScript is an interpreted language, so creating a sum function inside the prototype property of a Func function is assignment operation, not the declaration. If the return operator will be before the assignment, sum function will be simply ignored. That’s why you should keep the return operator in the very end of the service declaration.

Here is how the whole service looks with sum function:

Next, lets store all incoming arguments into a simple variable. Also, lets store $timeout service into a variable as well. And lastly, lets write a logic for asynchronous calculations:

Lets review in details the code above:

$q service called as function with a single argument – another function which will be called with two arguments:

  1. resolve function – in case of all calculations (or AJAX request) are successful. As argument for this function you can send any results.
  2. reject function – in cases of any error. In this example, this function will be called, if result of the calculations will be more then 100.

Also, $timeout service with 300 ms delay is used for emulating asynchronous calculations, which are usually done by AJAX requests.

Useful to know, that $timeout service can be used for lazy calculations. This can be helpful when you need to do some complex calculations and simultaneously update the UI. The thing is, that the page rendering and JavaScript code interpretation are done in the same thread. So it makes sense to render the UI initially, show spinner (or something that indicates loading process), and then make the calculations. Such approach will prevent UI to be freezed, because you can make sure that calculations are done only once the UI is fully loaded and displayed.

And the last step – calculations:

Read more about reduce method here.

Here is how the service finally looks:

Factory

Here is how the same example will look in case of implementation in factory form:

As you can see, in case of factoryreturn operator doesn’t need to be shifted down, because there is no any assignments in module body.

More then one resource in one file

You can create more then one service or factory in one file by adding new items into array returned by module:

Executing service in scope functions

To use any AngularJS resource on the page, use Apperyio.get() method. Go to page you need and switch to SCOPE tab. You can create new or use already existing methods. Here is how you can use custom service made in Creating custom service section in your scope methods (controller).

Service

Factory

Try to change numbers in sum method, so their sum will be more than 100. You’ll see, that in this case error is triggered.

Loading resources on demand

It’s often a good idea to load resources on demand instead of loading them all initially. Loading resources when needed will positively impact on page loading time. Here is how you can load on demand AngularJS resources:

  1. Remove resource you want from the global dependencies by going to Project > App settings > Resources and removing the tick in Global column. This way, your resource won’t be loaded during app launching:
    unchecked_global
  2. Now, add your resource as dependency for the page, where you need to use it. Go to Project > Routing and click Manage dependencies right to the needed page. Check your resource and click Save changes:
    checked_resource

Now your resource will be loaded only for certain page, not for the whole app.

Directives

Directives in AngularJS are used to make custom HTML elements and simplify DOM manipulations. They can also modify the behavior of new and existing DOM elements by adding custom functionality, such as a datepicker or an autocomplete widget. AngularJS comes with its own set of built-in directives, like ngBind, ngModel, and ngClass, as well as the ability to add your own.

.js files contain JavaScript code that is used to execute instructions in a Web page that uses client-side scripting. These functions may include the validation of form fields, rollover images, drop-down menu creation, etc.

Directives implementation

Appery.io comes with a wide selection of AngularJS directives which you can make use of.

Below are the links to the directives specifying custom behaviour on events:

The Autocomplete feature may be useful when entering/editing custom directives to define the app components.

To add a directive to your app in the Appery.io Visual Builder, open the DESIGN tab, select a component (for selecting components, you can also use the COMPONENTS TREE view), and pass the directive on the PROPERTIES tab:
pop-up

More information on AngularJS directives can be found here and here.

Directive code structure

Directive codes should have the following structure:

<directive name> – when declaring an AngularJS directive, the naming convention is camelCase.

For example, we would define the name of the directive as ‘navigateTo’. However, when you go to use the directive in your HTML, it will be the dash-separated version. That is, our widget would be <navigate-to> and not <navigateTo>.

<directive structure> – is a JSON.

For example:

Appery.io predefined directives

Once a user has created a new Appery.io project, two directives are added by default: backButton and navigateTo.

This can be found under Project > JavaScript:

Using a navigateTo directive

The navigateTo directive can be used to manage navigation from one page to another or across multiples pages within the app.

For example, to make your app navigate between the app pages (navigate to the Price page, and click on an item from the List page), you must:

1. Rename Screen1 to List and, in DESIGN, define the List item with the default Appery.io directive navigate-to (you may use prompts) with its Attribute value = Screen2.

2. Create another page named Price leaving Create navigation route for this page checked.

Additionally, you can pass some parameters while navigating between the screens. To do it:

1. For the List item, add another attribute: navigate-toquantity = 15:
quantity

2. Now, go to: Project > Routing and define the path for Screen2:

3. Click TEST, then: Remove frame. Here is how the app returns the info:
15

Here you can find more information on route navigation.

Using backButton directive

The backButton directive can be used in apps with a hierarchical navigation pattern for managing the browser’s history. The Back button will behave in an appropriate manner for the context of your application.

A simple way to use this directive is as follows:

1. Place a Button component on the Price page of your app (see above) and change its Text to Back to the list.

2. Add back-button for Attribute name (you may use prompts) and leave the Attribute value field blank:

Creating a custom directive

Almost everything we use in AngularJS is a directive. Directives are what makes AngularJS so powerful and responsive.

Although AngularJS comes with powerful directives, some users want to create their own.

Building an app with a custom directive

Let’s create a new app that will display the alert “Good bye!” by clicking on a button placed on the first screen. It will then redirect you to the main screen.

1. To add a new directive, go to CREATE NEW > JavaScript.

2. Enter the name (function, for example), select Angular directive as Type and click Create JavaScript.

3. Then, pass the following code into the code field (replacing the default code):

In the code, define the <deps> since redirection is required. Also, pass the alert for <link>. The page which you want to be redirected to has already been passed:

4. Then, drag & drop a Button component onto Screen1 and define the directive you have just created:

You may also make use of Autocomplete while entering the attribute name.

5. Now, add another page to the app: MainSreen leaving Create navigation route for this page checked.

6. Switch to the MainSreen and insert a Text component with some text:

7. Save.

Testing the app

Now, when you click TEST, you’ll go to the first screen with a Click me! button.

After clicking it, an alert is displayed.

After you clicking OK, you will be redirected to the MainScreen:Final

Signalling errors

Another useful feature of having a code editor is that it can signal the user about incorrect code entries. For example, if a user enters an invalid function, the prompt directive name disappears from the directives list:

To see the changes made, you must refresh the code editor by clicking outside of the code field.