Sometimes ng-click don't work in Ionic

I’m new IONIC & AngularJS. Currently, working on an app & stuck at a point. Don’t how to resolve the issue.

I’ve a login form. After user login to the app, he/she will land at HOME page. In the home page, I’ve an image. On that image, I’m using ng-click. So, on click of that image, it’ll redirect the user to some other page. Here I’m facing the issue & the issue is, just after login when I’m coming to the home page & on click of that image ng-click is not working at all. But, once I refresh the browser & click on that image ng-click start working. Don’t know why this wired thing is happening.

After some random testing, I found that… If I place the same “showVendorPage()” in my “Menu.js” controller file which handle the side menu functionality it started working(just after login). Then, If I refresh the page & click on Image then ng-click is working from my Home.js controller. I think, somewhere something is going wrong & my scope is not working properly.

Here are all files which I’m using. The ionic version which I’m using in 1.7.12

app.js

(function(){

    var app = angular.module('e2pro', ['ionic', 'e2pro.LoginController', 'e2pro.HomeController', 'e2pro.AttendanceController', 'e2pro.LogoutController','e2pro.MenuController','e2pro.EmpProfileController','e2pro.EmpSearchController', 'e2pro.VendorController', 'ngMessages', 'ngCordova', 'angularMoment']);

    var requestToken    = "";
    var accessToken     = "";
    var deviceToken     = null;
    var access_token    = null;
    var refresh_token   = null;
    var session_id      = null;
    var user_id         = null;
    var user_login_type = null;
    var route_to        = null;

    app.run(function($ionicPlatform, RequestsService, GeoAlert) {
        $ionicPlatform.ready(function() {
            // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
            // for form inputs)
            if (window.cordova && window.cordova.plugins.Keyboard) {
                cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
                cordova.plugins.Keyboard.disableScroll(true);
            }
            if (window.StatusBar) {
                // org.apache.cordova.statusbar required
                StatusBar.styleDefault();
            }

            console.log('inside app.run function');
        });

    });


    // Service for logout user from app
    app.factory("User", function($http, $q, $rootScope, $ionicHistory, $state) {
        return {
            logout: function(){
                window.localStorage.clear();
                $ionicHistory.clearCache();
                $ionicHistory.clearHistory();
                $ionicHistory.nextViewOptions({ disableBack: true, historyRoot: true });

                $state.go("login");
            }
        }
    });


    app.config(function($stateProvider, $urlRouterProvider, $httpProvider) {
        $stateProvider

        .state('app', {
            url: '/app',
            abstract: true,
            templateUrl: 'templates/menu.html',
            controller: 'MenuController'
        })

        .state('app.tabs', {
            url: "/tabs",
            views: {
                'menuContent': {
                    templateUrl: "templates/tabs.html",
                }
            }
        })

        .state('login', {
            url: "/login",
            templateUrl: "templates/login.html",
            //controller: 'LoginController'
        })

        .state('markEmpAttendance', {
            url: "/markEmpAttendance",
            templateUrl: "templates/attendance/markEmpAttendance.html",
            //controller: 'AttendanceController'
        })

        .state('app.tabs.home', {
            url: '/home',
            views: {
                'home-tab': {
                    templateUrl: 'templates/home.html',
                }
            }
        })

        .state('app.tabs.emp-profile', {
            url: '/emp-profile/:empId',
            views: {
                'home-tab': {
                    templateUrl: 'templates/empProfile.html',
                    //controller: 'EmpProfileController'
                }
            }
        })

        .state('app.tabs.vendor', {
            url: '/vendor',
            views: {
                'home-tab': {
                    templateUrl: 'templates/vendor/vendor.html',
                    //controller: 'EmpProfileController'
                }
            }
        })

        .state('app.tabs.emp-search', {
            url: '/emp-search',
            views: {
                'home-tab': {
                    templateUrl: 'templates/empSearch.html',
                    //controller: 'EmpProfileController'
                }
            }
        })

        .state('app.tabs.service-request', {
            url: "/articles",
            views: {
                'serviceRequest-tab': {
                    templateUrl: "templates/serviceRequest.html",
                    controller: 'articlesCtrl'
                }
            }
        })

        .state('app.tabs.colonies', {
            url: "/colonies",
            views: {
                'colonies-tab': {
                    templateUrl: "templates/colonies.html",
                    controller: 'coloniesCtrl'
                }
            }
        })

        .state('app.foo', {
            url: "/foo",
            views: {
                'menuContent': {
                    templateUrl: "templates/foo.html",
                    controller: 'fooCtrl'
                }
            }
        });

        $urlRouterProvider.otherwise('/app/tabs/home');
        $httpProvider.interceptors.push('sessionInjector');
    });

}());

login.js (controller file)

angular.module('e2pro.LoginController', [])

// Employee Attendance Controller
.controller('LoginController', function($http, $scope, $state, $ionicHistory, $ionicLoading, $cordovaOauth, RequestsService){
    console.log('Inside Login Controller');

    var baseUrl=null;

    $scope.credentials = {};
    $scope.validationFailed = false;

    $http.get('js/config.json')
            .then(function(res){
                baseUrl = res.data.server[res.data.mode];
            });


    // Method for user's default login
    $scope.validateCredentials = function(form){
        console.log('Form Validation start for login : '+form.$valid);
        var attendance_require = null;
        var emp_attendance_status = null;

        // Setting module data element for the api request
        $scope.credentials.module = 'user_login';
        $scope.credentials.pageId = 1548;

        // Check form validation status & move control accordingly
        if(!form.$valid)
        {
            return false;
        }

        // Show spinner animation
        $ionicLoading.show({
            template: '<ion-spinner icon="android"></ion-spinner>'
        });

        $http({
            method: 'POST',
            url: baseUrl+'/S/E2Pro_MobileApiEndPoint.php',
            data : $scope.credentials
        }).then(function successCallback(response) {
                if(response['data']['status'] === 'success')
                {
                    session_id    = response['data']['data']['session_id'];
                    user_id       = response['data']['data']['user_id'];
                    route_to      = response['data']['data']['route_to'];
                    attendance_require = response['data']['data']['attendance_require'];
                    emp_attendance_status = response['data']['data']['emp_attendance_status'];

                    window.localStorage.setItem("session_id", session_id);
                    window.localStorage.setItem("user_id", user_id);
                    window.localStorage.setItem("user_login_type", 'default');

                    // Hide Spinner before redirecting to home page
                    $ionicLoading.hide();

                    // Redirecting to home page
                    if(route_to === 'home'){
                        $state.go('app.tabs.home');
                        return false;
                    }
                }
                else
                {
                    // Hide Spinner before redirecting to home page
                    $ionicLoading.hide();

                    // Show message for email id & password miss match
                    $scope.validationFailed = true;
                }

            }, function errorCallback(response) {
                // console.log('Error occcur during user authentication');

                // Hide Spinner before redirecting to home page
                $ionicLoading.hide();
            });
    };

});

Home.js (Controller file)

angular.module('e2pro.HomeController', [])

// Employee Attendance Controller
.controller('HomeController', function($scope, $state, $location, $ionicHistory, $ionicSideMenuDelegate, $http, $ionicPopup, User, GeoAlert){

    console.log('Inside Home Controller');
    var baseUrl=null;

    // Check application session. If it's found not exist redirect user to login page
    if(window.localStorage.getItem("session_id") === "undefined" || window.localStorage.getItem("session_id") === null) {
        $ionicHistory.nextViewOptions({
            disableAnimate: true,
            disableBack: true
        });

        $state.go("login");
        return false;
    }

    $scope.empName               = '';
    $scope.alertMsgBox           = false;
    $scope.alertMsgText          = '';
    $scope.employees             = [];

    $http.get('js/config.json')
            .then(function(res){
                baseUrl = res.data.server[res.data.mode];
            });

    // Method for showing Vendor page
    $scope.showVendorPage = function(){
        console.log('Clicked on vendor icon');
        $state.go('app.tabs.vendor');
    }

});

Home.html (template file)

<ion-view view-title="Home">
	<ion-content class="has-tabs">

		<div ng-controller='HomeController' >
			<div class="row" style="margin-top:15px;">
				<div class="col">
					<img src="img/leave.png" ng-click="showVendorPage()">
					<h5>Vendor</h5>
				</div>
				<div class="col">.col</div>
				<div class="col">.col</div>
			</div>
		</div>

	</ion-content>
</ion-view>

Menu.js file

angular.module('e2pro.MenuController', [])

// Employee Attendance Controller
.controller('MenuController', function($scope, $state, $ionicHistory, User){
	// Method for logout user from app
    $scope.logout = function(){
        User.logout();
    };

    // Method for showing employee profile
    $scope.showSelfProfile = function(){
        empId = window.localStorage.getItem("user_id");
        // console.log('MenuCtrl - click on profile image of emp id : '+empId);

        // Redirecting to home page
        console.log('At func showSelfProfile');
        $state.go('app.tabs.emp-profile', {empId:empId});
    }

    // Method for showing employee search page
    $scope.showEmpSearchPage = function(){
        console.log('Cliked on employee search icon');
        $state.go('app.tabs.emp-search');
    }

    // Method for showing Vendor page
    $scope.showVendorPage = function(){
        console.log('Clicked on vendor icon from Menu Controller file');
        $state.go('app.tabs.vendor');
    }
});

Need some Guidance
Thanks

Hi,

Having a quick look at your code and from reading your description it may have to do with your digest cycle. If you have an asynchronous event (promise) passing in a variable to your app you need to let AngularJS know.
This can be done by wrapping it into a
$scope.$apply(function{ whatever you want to do... });

In your home.js you have:

$http.get('js/config.json') .then(function(res){ baseUrl = res.data.server[res.data.mode]; });

try it with:
$http.get('js/config.json') .then(function(res){ $scope.$apply(function{ baseUrl = res.data.server[res.data.mode]; }) });

Try and read up a bit more on promises and the digest cycle in angularJS:

http://andyshora.com/promises-angularjs-explained-as-cartoon.html


Also, Developer tools (inspect element) in chrome/firefox/safari can help you greatly in seeing what is going on behind the scenes. I tend to put
console.log("variable:" +variable)
in my code flow and detect the variables step by step.

I haven’t looked at your code in detail, but I encountered cases where “ng-click” didn’t work but “on-tap” worked fine. No idea why, just my 2 cents.

@whizzkey Thanks for the quick reply. Actually, because of some reason my testing server is down & I’ve no access to it. it’s again weekend at here. So, can’t able to make a quick test. Give me some time. I’ll workout on your suggestion & get back to you.

Thanks

@leob I’ve already tested that “on-tap” thing & it’s not working. Actually, the issue is with some kind SCOPE is overridden(don’t know the actual technical name). That’s why, this thing is happening. But, don’t know how to fix it.

Hey, I’ve checked that using $scope.$apply() over the baseUrl thing. But, it’s not working. Maybe somewhere the problem is. By the way, thanks for that $appy & $disgest stuff. I didn’t know about that.

it was worth a try…

I’ll have another look at your code in a bit.

can you place console.log("the value you wanna check: "+value);
throughout your workflow so you can see which values get assigned and when…
you can check your log through chrome/firefox/safari inspector