skip to Main Content

I have strange problem when loading different templates using Codeigniter and AngularJS. When i click on other link, templates gets redirected on some /undefined link. Let me show you my code.

This is my app.js

var app = angular.module('app', ['ngRoute']);
app.config(function($routeProvider){
    $routeProvider.
      when('/', {controller:'homeCtrl', templateUrl:'app/templates/home.html'}).
      when('/home', {controller:'homeCtrl', templateUrl:'app/templates/home.html'}).
      when('/contact', {controller:'contactCtrl', templateUrl:'app/templates/contact.html'}).
      otherwise({ redirectTo: '/home'});
  });

controllers.js

    var app = angular.module('app');
    var controllers = {};


controllers.headerCtrl = function($scope, categoriesFactory){ 
    //get available categories
    categoriesFactory.getCategoriesList().success(function(data){
        $scope.categories = data;
    }).error(function(e){
        console.log(e);
    });
}

controllers.homeCtrl = function($scope, productsFactory){
    productsFactory.getlatestProductsList(16).success(function(data){
        $scope.products = data;
    }).error(function(e){
        console.log(e);
    });
}

controllers.contactCtrl = function($scope, $http, $location){ 
    //Send message
    // creating a blank object to hold our form information.
    //$scope will allow this to pass between controller and view
    $scope.formData = {};
    // submission message doesn't show when page loads
    $scope.submission = false;
    // Updated code thanks to Yotam
    var param = function(data) {
        var returnString = '';
        for (d in data){
            if (data.hasOwnProperty(d))
                returnString += d + '=' + data[d] + '&';
        }
        // Remove last ampersand and return
        return returnString.slice( 0, returnString.length - 1 );
    };
    $scope.submitForm = function(){
        $scope.submissionMessage = '';
        $http({
            method : 'POST',
            url : $location.protocol() + '://' + $location.host() + '/server/contact/send_message',
            data : param($scope.formData), // pass in data as strings
            // set the headers so angular passing info as form data (not request payload)
            headers : { 'Content-Type': 'application/x-www-form-urlencoded' }
        }).success(function(data){
                if(!data.success){
                    var name = document.getElementById('Name').value;
                    var email = document.getElementById('email').value;
                    var subject = document.getElementById('subject').value;
                    var message = document.getElementById('message').value;
                    if(name.length == '' && email.length == '' && subject.length == '' && message.length == ''){
                        $scope.submissionMessage = data.messageError;
                    }
                    // if not successful, bind errors to error variables
                    $scope.errorName = data.errors.name;
                    $scope.errorEmail = data.errors.email;
                    $scope.errorSubject = data.errors.subject;
                    $scope.errorTextarea = data.errors.message;
                    $scope.submission = true; //shows the error message
                }else{
                    // if successful, bind success message to message
                    $scope.submissionMessage = data.messageSuccess;
                    $scope.formData = {}; // form fields are emptied with this line
                    $scope.submission = true; //shows the success message
                    $scope.errorName = '';
                    $scope.errorEmail = '';
                    $scope.errorSubject = '';
                    $scope.errorTextarea = '';
                }
        });
    };
}
app.controller(controllers);

Factorys.js

var app = angular.module('app');

//Factory for categories
app.factory('categoriesFactory', ['$http', '$location', function($http, $location){
    var factory = {};

    factory.getCategoriesList = function(){
        return $http.get($location.protocol() + '://' + $location.host() + '/server/api/categories');
    }

    return factory;
}]);

//Factory for products
app.factory('productsFactory', ['$http', '$location', function($http, $location){
    var factory = {};
    /*
    factory.getProductsList = function(){
        return $http.get($location.protocol() + '://' + $location.host() + '/server/api/products');
    }
    */
    factory.getlatestProductsList = function($n){
        return $http.get($location.protocol() + '://' + $location.host() + '/server/api/products/latest/'+$n);
    }

    return factory;
}]);

My HTML index.html

     <!DOCTYPE html>
    <html ng-app="app">
    <!--[if lt IE 7]>      <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
    <!--[if IE 7]>         <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
    <!--[if IE 8]>         <html class="no-js lt-ie9"> <![endif]-->
    <!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]-->
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <title>Trade inside europe</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width">
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
        <link rel="stylesheet" href="css/icomoon-social.css">
        <link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700,600,800' rel='stylesheet' type='text/css'>
        <link rel="stylesheet" href="css/leaflet.css" />
        <!--[if lte IE 8]>
        <link rel="stylesheet" href="css/leaflet.ie.css" />
        <![endif]-->
        <link rel="stylesheet" href="css/main.css" />
        <script src="js/modernizr-2.6.2-respond-1.1.0.min.js"></script>
    </head>
    <body>

    <!-- Navigation & Logo-->
    <div class="mainmenu-wrapper" ng-controller="headerCtrl">
        <div class="container">
            <nav id="mainmenu" class="mainmenu">
                <ul>
                    <li class="logo-wrapper"><a ng-href="#/home" target="_self"><img src="img/mPurpose-logo.png" alt="Multipurpose Twitter Bootstrap Template"></a></li>
                    <li class="active">
                        <a ng-href="#/home" target="_self">Home</a>
                    </li>
                    <li class="has-submenu">
                        <a href="#">Trade +</a>
                        <div class="mainmenu-submenu">
                            <div class="mainmenu-submenu-inner">
                                <div ng-repeat="c in categories track by $index">
                                    <h4 ng-if="c.parent == 0">{{c.category}}</h4>
                                    <ul ng-repeat="sub_c in categories track by $index">
                                        <li ng-if="sub_c.parent == c.id_category">
                                            <a href="#">{{sub_c.category}}</a>
                                        </li>
                                    </ul>
                                </div>
                            </div><!-- /mainmenu-submenu-inner -->
                        </div><!-- /mainmenu-submenu -->
                    </li>
                    <li>
                        <a ng-href="#/contact">Contact</a>
                    </li>
                </ul>
            </nav>
        </div>
    </div>

    <div ng-view></div>

    <!-- Footer -->
    <div class="footer">
        <!-- Footer content -->
    </div>
</div>
<!-- Javascripts -->
<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
<script>window.jQuery || document.write('<script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>')</script>
<script src="http://cdn.leafletjs.com/leaflet-0.5.1/leaflet.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="js/jquery.fitvids.js"></script>
<script src="js/jquery.sequence-min.js"></script>
<script src="js/jquery.bxslider.js"></script>
<script src="js/main-menu.js"></script>
<script src="js/template.js"></script>
<script src="https://code.angularjs.org/1.4.8/angular.js"></script>
<script src="https://code.angularjs.org/1.4.8/angular-resource.js"></script>
<script src="https://code.angularjs.org/1.4.8/angular-route.js"></script>
<script src="app/app.js"></script>
<script src="app/controllers.js"></script>
<script src="app/factorys.js"></script>
</body>
</html>

home.html

<div class="section">
    <div class="container">
        <h2>Latest added</h2>
        <div class="row">
            <div class="col-md-3 col-sm-6" ng-repeat="p in products track by $index">
                <div class="portfolio-item">
                    <div class="portfolio-image">
                        <a href="page-portfolio-item.html"><img src="#" alt="#"></a>
                    </div>
                    <div class="portfolio-info">
                        <ul>
                            <li class="portfolio-project-name">{{p.name}}</li>
                            <li>{{p.description | limitTo:100}}<span ng-if="p.description.length > 100 ">...</span></li>
                            <li class="read-more"><a href="page-portfolio-item.html" class="btn">Read more</a></li>
                        </ul>
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>

Contact.html

<div class="section section-breadcrumbs">
    <div class="container">
        <div class="row">
            <div class="col-md-6">
                <h1>Contact Us</h1>
            </div>
        </div>
    </div>
</div>

<div class="section">
    <div class="container">
        <div class="row">
        <!-- contact content -->
        </div>
    </div>
</div>

main-menu.js

var mainMenu = (function() {

    var $listItems = $( '#mainmenu > ul > li' ),
        $menuItems = $listItems.children( 'a' ),
        $body = $( 'body' ),
        current = -1;
    function init() {
        $menuItems.on( 'click', open );
        $listItems.on( 'click', function( event ) { event.stopPropagation(); } );
    }
    function open( event ) {
        var $item = $( event.currentTarget ).parent( 'li.has-submenu' ),
            idx = $item.index();
        if($item.length != 0){
            if( current !== -1 ) {
                $listItems.eq( current ).removeClass( 'mainmenu-open' );
            }
            if( current === idx ) {
                $item.removeClass( 'mainmenu-open' );
                current = -1;
            }
            else {
                $item.addClass( 'mainmenu-open' );
                current = idx;
                $body.off( 'click' ).on( 'click', close );
            }
            return false;
        }
        else window.location = $item.find('a').attr('href');
    }
    function close( event ) {
        $listItems.eq( current ).removeClass( 'mainmenu-open' );
        current = -1;
    }
    return { init : init };
})();

So what happens.
I go to my home_page (www.mypage.com) and page renders correctly with link www.mypage.com/#/.
Then i click on let say contact button in menu and i get redirected to http://mypage.com/undefined which provides 404 site.
If i press button back on browser i will be redirected to www.mypage.com/#/contact and page renders correctly

nginx.logs

==> /var/log/nginx/error.log <==
2016/01/06 12:24:46 [error] 11852#0: *142 open() "/var/www/html/testapp.com/public_html/undefined" failed (2: No such file or directory), client: 127.0.0.1, server: testapp.com, request: "GET /undefined HTTP/1.1", host: "testapp.com", referrer: "http://testapp.com/"

==> /var/log/nginx/access.log <==
127.0.0.1 - - [06/Jan/2016:12:24:46 +0100] "GET /undefined HTTP/1.1" 404 200 "http://testapp.com/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.80 Safari/537.36"

Explained in images:

First step opening home page
First step opening home page

Second step clicking on button contact
Second step clicking on button contact

Third step pressing button back
enter image description here

Forth step clicking another button like home
main menu missing

What is happening?

If you need any additional info, please let me know and i will provide.
Thank you in advance

2

Answers


  1. If your Given Code is correct then you have to change this

    controllers.contactCtrl = function($scope, $http, $location) {
    /// your code as you have used three service $scope, $http, $location components 
    }
    
    Login or Signup to reply.
  2. I suspect your problem is main-menu.js.

    ...
    else window.location = $item.find('a').attr('href');
    ...
    

    Your ‘Contact’ link:

    <li>
        <a ng-href="#/contact">Contact</a>
    </li>
    

    The a doesn’t have a href property, so it’s gonna do:

    window.location = 'undefined';
    

    Try adding href="#/contact" to your Contact link.

    I think Angular is bootstrapped client-side when you press the ‘back’ button, which is why the behaviour isn’t occurring when you press ‘back’ again.

    TLDR; change <a ng-href="#/contact">Contact</a> to <a ng-href="#/contact" href="#/contact">Contact</a>.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search