Before You Begin
Purpose
This tutorial shows you how to use the Oracle JavaScript Extension Toolkit (JET) with Oracle Mobile Cloud Service (MCS). To do this, we’ll walk through creating a simple mobile app, then use JET code snippets to connect to MCS. If you have your own app, you can follow this tutorial and change the snippets to suit your needs. You’ll learn about:
- Working with the JET tools
- Creating a hybrid mobile app
- Connecting to MCS using the JavaScript SDK
Time to Complete
About two hours, not including set up.
Background
The JavaScript Extension Toolkit (JET) is a collection of open source JavaScript libraries and a set of Oracle contributed JavaScript libraries. JET helps you efficiently build client-side applications that work with Oracle products and services, especially Oracle Cloud services. Before you begin, you should be good at Knockout.js, RequireJS, and JavaScript to work with JET.
What Do You Need?
If you’re starting from scratch, there’s a fair amount of set up for this tutorial. But it’s pretty straightforward. You need:
- MCS
Login with your username and password.
- JDK 8 (if you’re using Android. iOS doesn’t need
it.)
Download it here:
Java SE downloadsOnce that’s done, be sure to set the JAVA_HOME and JDK_HOME environment variables to the install location.
- JET
Install the JET Prerequisite Packages:
Prerequisites for Developing Applications with Oracle JET. Scroll down to Install the Prerequisite Packages.Next, install the JET Mobile Tooling:
Install Oracle JET Mobile Tooling - JET Yeoman Generator
- Apache Cordova
- Android and/or iOS (you need to have OS X)
Android: Install Android Tools
iOS: Install iOS Tools
When you’re done with installs, jump back to this tutorial. You should have:
MCS
JDK 8 (if developing for Android)
An IDE or text editor of your choice
JET Prereq Packages (Git, Node.js)
JET Mobile Tooling (Yeoman, Grunt, Bower)
JET Yeoman Generator (in addition to Yeoman)
Cordova
Android Tools (Android 4.4.2 or higher, a configured AVD, and Android Studio) or
iOS Tools (Xcode, and the iOS simulator)
Good to go? Let's get started.
Creating a JET Mobile Starter App
For this tutorial, you’ll use JET and MCS with a mobile app. If you have one, skip this part and go to Connecting to MCS. If you don’t have a mobile app, you can use these steps to create one. We’ll be working with Android in this example, but you can change the commands for iOS if that’s your platform.
Scaffolding a Mobile Application
The JET generator uses Yeoman to scaffold starter apps from templates. There are three different templates. In this tutorial, we’ll use the “navBar” template.
-
Open a command prompt and create a directory where you want your mobile application to be. Change the directory to this new folder and run the Yeoman generator for Oracle JET, setting the platform as needed. If you’re on a Mac, you can set the platform for both iOS and android. In Windows, the platform option can only be set for android:
yo oraclejet:hybrid --appName=JETMobileDemo --template=navBar --platforms=android
This command creates a hybrid app named “JETMobileDemo” using the “navBar” template. You can see the other template options here:
Yeoman Template OptionsWhen the command completes, you should see:
Done, without errors.
Oracle JET: Your app is ready! Change to your new app directory and try grunt build and serve...
To help you understand the folder structure that the template creates, look at the Hybrid Mobile App Directory Structure (you’ll see the template options again, but scroll down until you see the image of the folders). If you don’t have time to read about it, the cliff notes version is that the src directory is the site root for your application, and it holds the files that you can modify for your own application. At build time, the src files are copied to the hybrid directory. This is important so you avoid developing in the hybrid directory which gets overwritten by the grunt build task. You’ll hear about this again in the section Opening the JET Project for Editing.
Building and Serving the App
You can now build your starter template app and run it on a device or emulator using Grunt, part of the Android or iOS tooling.
-
Build the app. Set the platform as needed:
grunt build:dev --platform=android -
Run the app:
grunt serve --platform=android --destination=deviceThis command runs the Android .apk file built by the previous command on an Android device attached to your machine. If you’re on Android, we recommend you connect your device via USB for on-device viewing to speed things up. If your platform is iOS, the emulator will do just fine.
On the device or emulator, the starter template should look something like the image below. If running on iOS, or later versions of Android, the header navigation bar will be on the bottom of the page instead of the top. If you’d like to move the nav bar position or otherwise change the look of your app, you can use the JET built-in styles. Find out more about them in the Want To Know More? section at the end of this tutorial.
Description of the image Device Dashboard
Opening the JET Project for Editing
You’ll use grunt again to open your project, then begin to develop it.
-
Start a local web server to run the project:
grunt serve --platform=android --web
You can develop your app with the editor or
IDE of your choice. Earlier we mentioned that
when developing, make sure you edit files
under the src directory, not the hybrid/www.
That’s because when grunt build
executes, the files from the src directory are
copied and overwrite whatever is in the hybrid
directory. This feature, known as live reload,
can cause some heartbreak if you’re not
careful. Also, if you don’t want to run a full
build but just want to copy the files over
from src to hybrid/www, you can. This command
will delete everything under the hybrid/www
and then copy the src files over again:
grunt clean copy
Loading the Modules
JET uses RequireJS for loading modules. When you installed Oracle JET, the download included the RequireJS library and sample bootstrap file.
-
In the index.html file, only two script tags are needed to run in the browser; one for Require.js and one for main.js. The main.js file defines the Require configuration as well as the top level view model, named MainViewModel, which initializes the single-page application:
<script type="text/javascript" src="js/libs/require/require.js"></script> <script type="text/javascript" src="js/main.js"></script>
The MainViewModel also initializes the AppController.js view model object. The AppController defines the pages for the router and creates the navigation entries. Then the router is synchronized and the bindings are applied to the body of the index.html file.
If you’re wondering how Cordova.js fits in,
when grunt build:dev is
executed, watch for a step in the output that
reads “includeCordovaJs”. This step inserts
the cordova.js script tag below into the
hybrid/www/index.html file:
<script src=”cordova.js”></script>
You need Cordova.js when running on a device or emulator. But when you’re running in the browser, the script tag is going to cause a 404 error. No worries. On the other hand, if you see the same error on the device or emulator, you’ve got a small problem. The cordova.js file needs to be available when running on a device or emulator because the build process parks the cordova.js file in the platform directory. For Android the location is:
<project>\hybrid\platforms\android\platform_www\cordova.js
As you might have guessed, you can only test
Cordova plugin use on a device or
emulator/simulator because cordova.js is not
available when running in the browser. The
good news is that the live reload capabilities
using grunt serve makes it
quicker to update the app on the device when
you’re making changes.
To find out how JET uses Require.js, check out the Want to Know More? section of this tutorial.
Connecting to MCS
Now that your basic app is ready, you’ll continue to develop and configure it for connecting to MCS. It won’t take much time since MCS has a Javascript SDK that makes connecting to the mobile backend a cinch.
Creating a Login/Logout Page and Configuring the Project
In this section you’ll use the MCS JavaScript SDK to create a basic user/password login/logout page for your app, then you’ll configure your project. Later, you’ll finish up with some JET components with Knockout observables to set the username and password.
To create the user/password login/logout page:
- Download the MCS JavaScript SDK.
- In MCS, click the hamburger icon to open
the side menu and select Applications.

- Click SDK Downloads in the upper right. This takes you to the SDK Downloads page.
- Choose the MCS Javascript SDK for Cordova. Since you already have an app, download the SDK alone, without the starter app option.
- Unzip the file to a temp directory and find the mcs.js and mcs-min.js files.
- In MCS, click the hamburger icon to open
the side menu and select Applications.
- Add the SDK to the Project and Require.js configuration.
-
In your app project, under the src/js folder, create a new folder called “mcs”. Copy the mcs.js and mcs.min.js into this folder (see image below). Use the minified mcs-min.js file (the compressed version of the SDK) for these steps if you like.
Description of the image MCS Folder Structure - Update the Require.js configuration to include the MCS SDK.
- In the main.js file for the app, add a
reference in the Require config file for the
MCS JavaScript SDK. You can reference the
mcs.js or minified mcs.min.js. The
configuration below uses the non-minified
version. Notice this line is added:
'mcs': 'mcs/mcs'
Config portion of main.js for the non-minified version.
requirejs.config(
{
baseUrl: 'js',
// Path mappings for the logical module names
paths:
//injector:mainReleasePaths
{
'knockout': 'libs/knockout/knockout-3.4.0.debug',
'jquery': 'libs/jquery/jquery-2.1.3',
'jqueryui-amd': 'libs/jquery/jqueryui-amd-1.11.4',
'promise': 'libs/es6-promise/promise-1.0.0',
'hammerjs': 'libs/hammer/hammer-2.0.4',
'ojdnd': 'libs/dnd-polyfill/dnd-polyfill-1.0.0',
'ojs': 'libs/oj/v2.0.0/debug',
'ojL10n': 'libs/oj/v2.0.0/ojL10n',
'ojtranslations': 'libs/oj/v2.0.0/resources',
'text': 'libs/require/text',
'signals': 'libs/js-signals/signals',
'mcs': 'mcs/mcs'
}
//endinjector
,
// Shim configurations for modules that do not expose AMD
shim:
{
'jquery':
{
exports: ['jQuery', '$']
}
}
}
);
Now your app should look like this:
The login/logout page is pretty basic at this point. If you’re game, you can add to it from a wide variety of UI components in the JET Cookbook. You can find the JET Cookbook in the Want to Know More? section of this tutorial.
Working with the Backend
Next, you’ll get ready to connect to MCS.
- Get the MCS URL and Keys.
- Login to the MCS console and select the mobile backend that your app will use.
- Click on the Settings page.
- In the Authentication Keys list, find Client Secret and click Show. These are the URLs and keys for the mobile backend that you will be using to connect your app to the MCS backend.
- Create the view model that initializes the MCS mobile backend for the app.
- Create a folder called mbe, for “Mobile Backend”.
- Create a folder called mbe.js for the JavaScript.
- Configure the application connection to the mobile backend in MCS.
- Change the keys in the code to your MCS backend keys and insert this code into the file. It’s explained below.
- The configuration is defined for a backend called JETSample. This name doesn’t have to match the name of the backend that is actually in MCS, but it can if you want.
- The mcs reference is included in the define array of dependencies. This reference is available because the Requires.js configuration in main.js was already updated in an earlier step.
- The mcs_config object contains the URL and keys for accessing MCS. The basicAuth and OAuth portions of the object are defined, but only basicAuth is used in the example.
- The init() method in the file declares and initializes the MCS backend object, setting the authentication type to basic auth.
- The methods defined are for login and logout of the backend. A method for anonymous authentication is included but isn’t used. The authenticate and logout methods will be used for the dashboard page to work with JET components for a basic login page.
You need to create an interface to MCS so you can interact with it from the app. Since the MCS JavaScript SDK is already available to the app, just create a new JavaScript file to call the MCS methods that the application needs to use.
These folders should be at the same level as the mcs folders you created, like this:
mbe.js
define(['jquery', 'mcs'], function ($) {
//define MCS mobile backend connection details
var mcs_config = {
"logLevel": mcs.logLevelInfo,
"mobileBackends": {
"JETSample": {
"default": true,
"baseUrl": "https://mobileportalsetrial-yourdomain.mobileenv.us2.oraclecloud.com:443
"applicationKey": "0fc655f4-5ebb-4876-b9e4-352be9a2f491",
"authorization": {
"basicAuth": {
"backendId": "b93925cf-7c60-4cda-a3e0-2f0358c9eff2",
"anonymousToken": "WjE3R1NFQUNDVDI3NDIwNTUxMjFfTU9CSUxFUE9SVEFMU0VUUklBTDExNjVERVZfTU9CSUxFX0FOT05ZTU9VU19BUFBJRDphSjVfdHpmZ3FqaTJoYg=="
},
"oAuth": {
"clientId": "1f305979-2c24-4667-b80e-5893877ca24e",
"clientSecret": "mysecretkey",
"tokenEndpoint": "https://yourdomain.identity.us.oraclecloud.com/oam/oauth2/tokens"
}
}
}
}
};
function MobileBackend() {
var self = this;
self.mobileBackend;
function init() {
mcs.MobileBackendManager.setConfig(mcs_config);
//MCS backend name for example is JETSample.
self.mobileBackend = mcs.MobileBackendManager.getMobileBackend('JETSample');
self.mobileBackend.setAuthenticationType("basicAuth");
}
//Handles the success and failure callbacks defined here
//Not using anonymous login for this example but including here.
self.authAnonymous = function () {
console.log("Authenticating anonymously");
self.mobileBackend.Authorization.authenticateAnonymous(
function (response, data) {
console.log("Success authenticating against mobile backend");
},
function (statusCode, data) {
console.log("Failure authenticating against mobile backend");
}
);
};
//This handles success and failure callbacks using parameters (unlike the authAnonymous example)
self.authenticate = function (username, password, successCallback, failureCallback) {
self.mobileBackend.Authorization.authenticate(username, password, successCallback, failureCallback);
};
//this handles success and failure callbacks using parameters
self.logout = function (successCallback, failureCallback) {
self.mobileBackend.Authorization.logout();
};
init();
}
return new MobileBackend();
});
Here’s what’s going on:
Finishing Up the Project
There are a few more things to take care of to finish the project. First, you’ll add a login form to your app. The JET cookbook is great for understanding how to add form elements and buttons into a view and viewModel. You’ll need some Knockout knowledge to use JET components. You can get up to speed with Learn KnockoutJS in the Want to Know More? section of this tutorial.
- Add a username and password field using JET components. Do that by replacing your starter app’s dashboard.html page with this HTML. It’s explained below.
- The Knockout
visiblebinding is used to hide and show elements based on the login status. That means the login form is only visible when the user is not authorized. The logout button is only visible when the user is authorized. - The username and password entry field values are bound to Knockout observables defined in dashboard.js.
- JET bindings for form inputs use the “value” attribute.
- The login button is bound on the click event to a function in the view model called login. Likewise, the logout button is bound on a click event to a logout function in the view model.
- Additional elements that are going to be used have comments.
- Edit the dashboard view model.
- The proper dependencies in the define method on the first line are included. The Mobile Backend helper class needs to be added here as a reference in order to make calls to the MCS API that we created in mbe.js.
- Additional references are needed for JET components used on the page, in this case buttons and form inputs. Three Knockout observables are defined, one for the login status, one for the username, and one for the password. These are bound in the html to the JET input components. The login status is used to hide or show the login form or logout button based on the status (true or false). The username and password are initialized to working values so no typing is required in testing the login.
- The methods
authenticateandlogoutcall the Mobile Backend helper object’s methods to handle calls to MCS. In theloginmethod, callbacks are passed to the Mobile Backend helper so that with success or failure, the dashboard view model can react. - Test your app’s login and logout.
- If needed, run:
- Next, run
grunt serve: - Set the Meta Tag in Cordova.
dashboard.html
<div class="oj-hybrid-padding">
<h3>Dashboard Content Area</h3>
<div>
<div data-bind="visible: !isLoggedIn()" class="oj-flex oj-sm-flex-direction-column oj-md-flex-direction-column">
<div class="oj-flex-item">
<label for="text-input">Username</label>
<input id="text-input"
type="text"
data-bind="ojComponent: {component: 'ojInputText',
value: username}"/>
</div>
<div class="oj-flex-item">
<label for="password">Password</label>
<input type="password"
id="password"
data-bind="ojComponent: {component: 'ojInputPassword',
value: password}"/>
</div>
<div class="oj-flex-item">
<input id="inputButton" type="button"
data-bind="click: login,
ojComponent: {component: 'ojButton', label: 'Login', chroming: 'full'}"/>
</div>
</div>
</div>
<div data-bind="visible: isLoggedIn">
<input id="inputButton" type="button"
data-bind="click: logout,
ojComponent: {component: 'ojButton', label: 'Logout', chroming: 'full'}"/>
</div>
</div>
Here’s what’s going on:
Now that you changed the dashboard.html page, you also need to update the view model to handle login/logout. Replace the dashboard.js file with this JavaScript. It’s explained below.
dashboard.js
define(['ojs/ojcore', 'knockout', 'jquery', 'mbe/mbe', 'ojs/ojknockout', 'ojs/ojselectcombobox', 'ojs/ojbutton', 'ojs/ojinputtext'],
function (oj, ko, $, mbe) {
function DashboardViewModel() {
var self = this;
self.isLoggedIn = ko.observable(false);
//set these to defaults to enable login testing
self.username = ko.observable("jetuser");
self.password = ko.observable("Bonvenon1!");
//pass callbacks to the login to trigger page behavior on success or failure
self.login = function () {
mbe.authenticate(self.username(), self.password(), self.loginSuccess, self.loginFailure);
};
//pass callbacks to the login to trigger page behavior on success or failure
self.logout = function () {
mbe.logout();
self.isLoggedIn(false);
};
self.loginSuccess = function (response) {
console.log(response);
self.isLoggedIn(true);
};
self.loginFailure = function (statusCode) {
self.isLoggedIn(false);
alert("Login failed! " + statusCode);
};
}
return new DashboardViewModel;
}
);
Here’s what’s going on:
grunt clean copy
This will get all the updated files in place.
grunt serve --platform=android --web
After login, the Knockout visible
binding on the isLoggedIn
observable hides the form and shows the logout
button, as seen below:
Dealing with CORS Errors
When you’re testing in a browser and you use your app to call backend services on MCS, you may get a Cross-Origin Request (CORS) error.This will show up as a “HTTP Allow Access Origin Header” error. Here’s an example error message:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://mymcshost.mobileenv.us2.oraclecloud.com/mobile/platform/users/login. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).
To avoid this error, administrators can change the Security_AllowOrigin environment policy from the default value of “disallow” to “allow”. See the Mobile Cloud Services Environment Policies in the MCS User Guide.
You’ll probably want to set the Content Security Policy Header meta tag in your app. If the tag is not set, you’ll get a warning in the browser while the app is running on Android.
Insert the default declaration below into the index.html file in the head. You may have to change the declaration depending on your needs. Also, for production you should consider changing this to point only to the MCS host and any specific hosts that your app needs to communicate with.
<!--Allows connection to any host. Consider changing this to point to your MCS host: connect-src 'self'
http://mobilecloudservicehost -->
<meta http-equiv="Content-Security-Policy" content="default-src * data: gap:; script-src 'self' 'unsafe-inline' 'unsafe-eval' 127.0.0.1:* localhost:*; style-src 'self' 'unsafe-inline'; media-src *"/>
For more information on the meta tag and Cordova security best practices, see the Cordova whitelist-plugin GitHub page and the Cordova security guide in the Want to Know More? section of this tutorial.
What’s Next?
That wraps up this tutorial. You’ve got a hybrid mobile app and you know how to use JET to connect to MCS. If you haven’t already done so, try adding to your app with the JET cookbook and JET styles. You can also dig into the JET Developer Guide and learn how to add responsive design, use and customize themes, add a Cordova camera Plugin, or learn about the Oracle Alta UI design system to make your app even better. You’ll find resources in the Want to Know More? section coming up next.
Want to Know More?
-
Learn KnockoutJS tutorial
-
Use RequireJS in an Oracle JET application from the JET Developer Guide
-
Cordova Plugin Whitelist on GitHub
-
Add a Cordova camera plugin dev blog