Web development using Ionic 2 and Mobile Foundation
Andrii Vasylchenko May 02, 2018
MobileFirst_Foundation Mobile_Foundation Mobile_Foundation_Service Ionic Bluemix WebOverview:
We all know that IBM MobileFirst Foundation can be used to develop pure web applications. Ionic, which is one of most popular hybrid development frameworks, since version 2 also fully support web development. This blog post is targeted to show up how to setup web development environment combining Ionic 2 Framework with CLI and Mobile Foundation Bluemix service with Web SDK
Prerequisites:
While in general it is well known how to setup all of required components separately, i would highly recommend to read following materials:
Additionally to follow our quick start sample you will need to have following packages installed: node, npm, maven, python, cordova, ionic. You also need to setup Mobile Foundation Bluemix service and mfpdev-cli before continue.
Challenges:
After reading general setup guides for web development with IBM MobileFirst Foundation we can highlight several challenges that needs to be resolved in order to setup web development environment with Ionic 2
-
MobileFirst Foundation Web SDK installation will not lead to SDK appearance under www/build folder due to Ionic 2 build nature using npm scripts. We will need either manually copy ibm-mfp-web-sdk folder from node_modules and loose “npm update” benefits or design a better option
-
“mfpdev app preview” command won’t work due to a “no mobile platforms” related error. So we will need to use “ionic serve” or setup our own live-reload server
-
We will face “Access-Control-Allow-Origin” error, cause our dev server will be on Bluemix and we will make cross-domain requests. We will need to handle redirect either manually with our live-reload server config or push ionic live-reload server to do it for us
Quick start
Note: In this blogpost we will be using Ionic 2 RC.4
Let’s start with creating a simple ionic 2 (TypeScript) based project. Open terminal and type the following command:
ionic start websample blank --v2 --ts
Where websample
is our project name, blank
is the name of smallest ionic 2 project template and other 2 parameters specifies ionic version and typescript usage.
By default, depending on your operation system, you may have native platform installed automatically. In our demo case, cause we are on Mac OS, iOS platform was added. We can check what platforms are installed by using following commands:
cd websample
ionic platform list
We need to remove all installed platforms and then add “browser” to proceed with web development approach
ionic platform remove ios
ionic platform add browser
Now we can add MobileFirst Foundation Web SDK using NPM. For that type in terminal:
npm install ibm-mfp-web-sdk --save
--save
will mean that this plugin will be saved to root node_modules folder with all dependencies and installation will touch package.json by adding it to dependencies list.
We are going to solve our first challenge by using Ionic 2 app-scripts. You can learn about them more here. In particular we will need to modify ionic_copy script config, located under node_modules/@ionic/app-scripts/config/copy.config.js
, that is responsible for copying any kind of files during ionic build process. Add the following code after last copyPolyfills
task:
copyMFPcore: {
src: ['/node_modules/ibm-mfp-web-sdk/*.js'],
dest: '/mfp'
},
copyMFPmessages: {
src: ['/node_modules/ibm-mfp-web-sdk/lib/messages/**/*.json'],
dest: '/mfp/lib/messages'
},
copyMFPanalytics: {
src: ['/node_modules/ibm-mfp-web-sdk/lib/analytics/*.js'],
dest: '/mfp/lib/analytics'
},
copySJCL: {
src: ['/node_modules/sjcl/*.js'],
dest: '/mfp/node_modules/sjcl'
},
copyJSSHA: {
src: ['/node_modules/jssha/src/*.js'],
dest: '/mfp/node_modules/jssha/src'
},
copyPromiz: {
src: ['/node_modules/promiz/*.js'],
dest: '/mfp/node_modules/promiz'
}
Where copyMFPcore
responsible for copying ibmmfpf.js, copyMFPanalytics
for ibmmfpfanalytics and other are their dependencies.
Note: We are placing sjcl,jssha and promiz under
node_modules
folder cause ibmmfpf.js script is looking for them using relative path.
The whole file now should look like this
module.exports = {
copyAssets: {
src: ['/assets/**/*'],
dest: '/assets'
},
copyIndexContent: {
src: ['/index.html', '/manifest.json', '/service-worker.js'],
dest: ''
},
copyFonts: {
src: ['/node_modules/ionicons/dist/fonts/**/*', '/node_modules/ionic-angular/fonts/**/*'],
dest: '/assets/fonts'
},
copyPolyfills: {
src: ['/node_modules/ionic-angular/polyfills/polyfills.js'],
dest: ''
},
copyMFPcore: {
src: ['/node_modules/ibm-mfp-web-sdk/*.js'],
dest: '/mfp'
},
copyMFPmessages: {
src: ['/node_modules/ibm-mfp-web-sdk/lib/messages/**/*.json'],
dest: '/mfp/lib/messages'
},
copyMFPanalytics: {
src: ['/node_modules/ibm-mfp-web-sdk/lib/analytics/*.js'],
dest: '/mfp/lib/analytics'
},
copySJCL: {
src: ['/node_modules/sjcl/*.js'],
dest: '/mfp/node_modules/sjcl'
},
copyJSSHA: {
src: ['/node_modules/jssha/src/*.js'],
dest: '/mfp/node_modules/jssha/src'
},
copyPromiz: {
src: ['/node_modules/promiz/*.js'],
dest: '/mfp/node_modules/promiz'
}
}
We will use “ionic serve” to overcome second challenge, but for that there is a need to setup url forwarding, similar to how it done here. Ionic 2 cli has build-in proxy capabilities and we just need to configure them by editing ionic.config.json file in root folder of our project. Details about how to use proxy can be found here
"proxies": [
{
"path": "/mfp",
"proxyUrl": "https://mobilefoundation-hello-world-web-sample.mybluemix.net:443/mfp"
}
]
where proxyUrl
is our path to Bluemix based Mobile Foundation instance and mfp
is our runtime name. This will automatically forward all requests that comes to /mfp
(for example /mfp/api/adapters/javaAdapter/resource/unprotected
) to https://mobilefoundation-hello-world-web-sample.mybluemix.net:443/mfp/api/adapters/javaAdapter/resource/unprotected
instead of calling it from localhost.
Next step for us will be to load our ibmmfpf.js inside index.html head section. For that open index.html from src folder and add the following line before end of <HEAD>
<script type="text/javascript" src="build/mfp/ibmmfpf.js"></script>
Note: Make sure you are adding it to src/index.html and not www/index.html, cause last one will be rewritten during build process.
To be able to use WL API we need to add typings reference. This can be done by opening file src/declarations.d.ts
and adding the following line
/// <reference path="../node_modules/ibm-mfp-web-sdk/lib/typings/ibmmfpf.d.ts" />
Note: Make sure you put “///” before reference tag
Let’s also add a client side code to verify server connectivity and simple adapter call. In our quick start sample we will do it in src/pages/home/home.ts
file. We will add MfpInit function under HomePage class
MfpInit() {
console.debug('-- trying to init WL client');
var wlInitOptions = {
mfpContextRoot : '/mfp',
applicationId : 'com.ibm.websample'
};
WL.Client.init(wlInitOptions).then(
function() {
console.debug('-- WL client init done');
console.debug('-- trying to obtain authorization token');
WLAuthorizationManager.obtainAccessToken().then(
function(success){
console.debug('-- succesfully got a token');
console.debug('-- trying to call unprotected adapter');
var resourceRequest = new WLResourceRequest(
"/adapters/javaAdapter/resource/unprotected/",
WLResourceRequest.GET
);
resourceRequest.send().then(
function(response) {
console.debug("-- success: " + response.responseText);
},
function(response) {
console.error("-- failure: " + JSON.stringify(response));
}
);
},
function(failure){
console.error('-- failed to get a token');
}
);
});
}
And then will make sure it is called from constructor
this.MfpInit();
Whole file will look like this
import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
constructor(public navCtrl: NavController) {
this.MfpInit();
}
MfpInit() {
console.debug('-- trying to init WL client');
var wlInitOptions = {
mfpContextRoot : '/mfp',
applicationId : 'com.ibm.websample'
};
WL.Client.init(wlInitOptions).then(
function() {
console.debug('-- WL client init done');
console.debug('-- trying to obtain authorization token');
WLAuthorizationManager.obtainAccessToken().then(
function(success){
console.debug('-- succesfully got a token');
console.debug('-- trying to call unprotected adapter');
var resourceRequest = new WLResourceRequest(
"/adapters/javaAdapter/resource/unprotected/",
WLResourceRequest.GET
);
resourceRequest.send().then(
function(response) {
console.debug("-- success: " + response.responseText);
},
function(response) {
console.error("-- failure: " + JSON.stringify(response));
}
);
},
function(failure){
console.error('-- failed to get a token');
}
);
});
}
}
Now we can deploy java adapter from samples (or pre-build version from here)
Register our application with applicationID “com.ibm.websample” in MobileFirst Operations Console
Note: Make sure you set Application ID to “com.ibm.websample” during web application registration
And, finally, start our live reload server using Ionic CLI
ionic serve
You should now be able to see in Developer’s console messages about successful WL client int, obtained token and adapter call.
Conclusion
We managed to prepare our web development environment and quick start client-side application with Ionic 2 and IBM MobileFirst Foundation. By following this blog you will have everything you need to start creating your first web apps.
In case you want to start with already made sample or you are interested to see how security will work with web sdk, feel free to clone existing MFPF WebSDK with Ionic 2 sample from github
Inclusive terminology note: The Mobile First Platform team is making changes to support the IBM® initiative to replace racially biased and other discriminatory language in our code and content with more inclusive language. While IBM values the use of inclusive language, terms that are outside of IBM's direct influence are sometimes required for the sake of maintaining user understanding. As other industry leaders join IBM in embracing the use of inclusive language, IBM will continue to update the documentation to reflect those changes.