0

I've been trying to build a hybrid web app using Worklight and AngularJS and I'm having trouble getting the navigation working on a device. I have a simple main screen with a single button. Once I click this button it should take me to page 2 (serviceList page). When I press the button nothing happens. Actually I now have two buttons on the page, one using the <a href> tag and the other uses an ng-click="viewServiceTickets()" and in the viewServiceTickets() function I use the $location.path('serviceList'); (also tried '/serviceList' and '#/serviceList' as some people have been suggesting) but to no avail.

If I run it:

  • In the preview mode - it works
  • In the mobile browser simulator - it works
  • In the iOS simulator - it works
  • On an iOS device - IT FAILS (i.e. when I press either the button or the <a href, nothing happens and I see no errors in the log.

My angular config looks like this

var serviceApp = angular.module('serviceApp', ['ngRoute', 'ngTouch']);
var serviceControllers = {};
serviceApp.controller(serviceControllers);

serviceApp.config(function ($compileProvider){
    $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|tel):/);
});

//This configures the routes and associates each route with a view and a controller
serviceApp.config(function ($routeProvider) {
    $routeProvider
        .when('/',
            {
                controller: 'HomePageController',
                templateUrl: 'views/HomePage/homePage.html'
            })
        .when('/serviceList',
            {
                controller: 'ServiceTicketListController',
                templateUrl: 'views/ServiceTicketList/serviceTicketList.html'
            })
        .otherwise({ redirectTo: '/' });
});

And my main.js file has

function wlCommonInit(){
    document.addEventListener("deviceready", onDeviceReady, true);
}


function onDeviceReady() {
    angular.bootstrap(document);

}

The home page is very simple

<div id="splashPage">
    <div>
        <h2>Service Ticket Viewer</h2>
        <button type="button"  data-ng-click="viewServiceTickets()">View Service Tickets</button>
        <div class="mainBtnContainer"> 
            <a href="#/serviceList" >
                <img src="images/technical-support.png">
            </a>
        </div>

    </div>
</div>

And finally my controller is

serviceControllers.HomePageController = function ($scope, $location, $window, TicketService) {


    $scope.currentServiceTicket = {};    

    init();

    function init() {
        console.log("Initialisation of HomePageController complete");
    }

    $scope.viewServiceTickets = function() {
        //$locationProvider.html5Mode(true);
        $location.path("/serviceList");
    };

    $scope.goBack = function() {
        console.log("Going Back");
        $window.history.back();
    };


};

I've looked and tried a number of suggestions already which don't appear to work for me:

I forgot to add my main index.html page. All page fragments are injected into the div with the data-ng-view directive.

<!DOCTYPE HTML>
<html data-ng-app="serviceApp">
<head>
<meta charset="UTF-8">
<title>index</title>
<meta name="viewport"
    content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=0">

<meta name="format-detection" content="telephone=no">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">


<link rel="shortcut icon" href="images/favicon.png">
<link rel="apple-touch-icon" href="images/apple-touch-icon.png">
<link rel="stylesheet" href="css/main.css">

<script>window.$ = window.jQuery = WLJQ;</script>

<script src="js/angularjs/angular.js"></script>
<script src="js/angularjs/angular-touch.js"></script>
<script src="js/angularjs/angular-route.js"></script>
<script src="js/angularjs/angular-animate.js"></script>

</head>
<body style="display: none;">

    <div>
        <div data-ng-view=""></div>
    </div>

    <script src="js/initOptions.js"></script>
    <script src="js/main.js"></script>
    <script src="js/messages.js"></script>

    <script src="js/router.js"></script>

    <!-- Controllers -->
    <script src="views/HomePage/homePageController.js"></script>
    <script src="views/ServiceTicketList/serviceTicketListController.js"></script>
    <script src="views/ServiceTicketDetails/serviceTicketDetailsController.js"></script>

    <!-- Services -->   
    <script src="js/models/serviceTickets.js"></script>


</body>
</html>

I'm running in Worklight Studio 6.1 and angularjs 1.2.13

Any ideas? I'm sure (hoping) it's something silly that I've done/haven't done.

Community
  • 1
  • 1
  • IMO the question title is misleading. This question has got nothing to do with AngularJS. It is about navigating between pages in a Worklight-based app. – Idan Adar Feb 19 '14 at 15:20
  • @Idan: Not really as AngularJS has a mechanism for handling single page apps and that is what I'm trying to do. I tried the default mechanism and it works on everything but the device. So it may just be that the AnglularJS model for handling SPA is not compatible with WL. I was hoping to do it without using any JQuery capabilities, but that might not be possible. I'll give it a go using the std method and see how to integrate Angular to that. –  Feb 20 '14 at 01:23
  • Also, I know that there are differences between the iOS simulator and the device, but I'm also intrigued as to why it only fails on the device. –  Feb 20 '14 at 01:40

2 Answers2

2

Duh!! Silly mistake actually. Knew it had to be something simple.

It took me a while to track down as no errors are shown in the logs. I attached Safari web instpector and saw nothing. Then I used switched to the debugger and set a breakpoint on "All exceptions" and then I saw the error "file not found"

The problem was the web and iOS simulator are case insensitive to file names whereas the device is case sensitive. So just a typo in the filename.

For me this is good news as Angular is a nice way to manage two-way data bindings and also the routing in SPA and works nicely with Worklight without the need for JQuery/Dojo etc.

0

This IMO is not so much related to AngularJS... and the way you currently use to navigate between pages should actually fail for you anywhere in your Worklight app.

I suggest that you start by reading the training material provided for this purpose, and understand the concept of Worklight being a Single Page Application.

You must not use something like <a href="pages/page2.html"> in order to navigate between pages in your application. By doing so you navigate away from the application's main HTML file (index.html) thus losing the Worklight context. It is this "context", basically all the references in the HTML file to the CSS and JS files, that glue the app together. When this loss happens, the application will stop functioning.

There are also numerous questions on this subject by now, take a look at these and search for others if required:

Also take a look at the following example projects.
They are not using AngularJS, rather they explain how to navigate between pages in a Worklight-based app by using either jQuery's load or jQuery Mobile's changePage / pageShow.

On top of this, as long as you navigate properly between pages, you can add any framework you'd like in order to build your app, be it AngularJS or otherwise.


Also note that the eventListener for deviceready is completely not needed. The fact you've reached wlCommonInit() and that your code is being executed, means that Cordova (an integral part of the Worklight framework), has loaded successfully and deviceready was called (internally). You should remove this eventListener.

Community
  • 1
  • 1
Idan Adar
  • 44,156
  • 13
  • 50
  • 89