AngularJS controllers in separate files not identifying the scope - angularjs

I am learning AngularJS and so far I have the beginnings of a skeleton app, with a main index page and two templates: a login page and a home page which have very simple controllers. I have not reached deeper in the skeleton yet so I am trying to accomplish is much more basic than say authentication.
The reason why I coded the way I did is to try to apply a concept I read about in my time learning AngularJS; which is to modularize your code by giving each template (or partial) it's own controller in it's own JS file. I believe that this is a best practice that I should apply early on, as this will potentially grow a lot into the future. That is the reason why I am staying away from putting my controllers in a single file, which I know works quite well.
Now without further ado, please look at the following code for a reference of where I stand currently:
index.html
<!DOCTYPE html>
<html ng-app="MyApp">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>MyApp</title>
<link rel="stylesheet" href="assets/css/normalize.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="assets/css/animate.css">
<link href="https://netdna.bootstrapcdn.com/font-awesome/4.0.0/css/font-awesome.css" rel="stylesheet">
</head>
<body>
<div ng-view>
<!-- loaded view here -->
</div>
<!-- JS imports -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/3.6.0/lodash.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-route.js"></script>
<script src="assets/js/app.js"></script>
</body>
</html>
app.js
angular.module('MyApp', [
'ngRoute'
])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when("/login", {
templateUrl: 'assets/partials/login.html',
controller: 'LoginCtrl'
})
.when("/home", {
templateUrl: 'assets/partials/home.html',
controller: 'HomeCtrl'
})
.otherwise({
redirectTo: '/login'
});
}]);
login.html, home.html
<div class="container-fluid text-center">
<h2>{{pageTitle}}</h2>
</div>
login.js
angular.module('MyApp')
.controller('LoginCtrl', ['$scope', function($scope) {
$scope.pageTitle = "Hello! Sign In";
}]);
home.js
angular.module('MyApp')
.controller('HomeCtrl', ['$scope', function ($scope) {
$scope.pageTitle = "Welcome to the Home Page!";
}]);
So what is the issue I am working through? {{pageTitle}} is what is being displayed when the view is loaded, rather than the actual value passed in through the scope. Please let me know what is wrong here, I am open to all suggestions regarding how to improve my code, all help is highly appreciated!

You have not included your login.js and home.js to index.html file. Also you do not need to include angular.module('MyApp') in all the file. It is there already in app.js and same instance can be used here too.
You can just do
MyApp.controller('HomeCtrl', ['$scope', function ($scope) {
$scope.pageTitle = "Welcome to the Home Page!";
}]);
MyApp.controller('LoginCtrl', ['$scope', function($scope) {
$scope.pageTitle = "Hello! Sign In";
}]);

You need to include the home.js and login.js controller in html after app.js
<script src="assets/js/app.js"></script>
<script src="assets/js/home.js"></script>
<script src="assets/js/login.js"></script>
You can also create a file name controller.js and add all of the controller in it for simple project, that way you don't have to make new request for js file from html.

Related

Using angular ui.router how to start in a standard html angular page and than move forward to one with ui.router template inside a folder?

I have a standard angular page that is not associated with any ui.router functionality(index.html). From that page I click a link that triggers an angular call and than after some operation the flow needs to be redirected to a page inside a folder that is using angular-ui.route template.
I have created a plunker that represents this:
http://plnkr.co/edit/7UQTlMRQBMXGaRdHlPfs?p=preview (current plunker is working but there's a loop on first page trying to call default state created with $urlRouterProvider.otherwise('events');)
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js#1.3.16" data-semver="1.3.16" src="https://code.angularjs.org/1.3.16/angular.js"></script>
<script data-require="ui-router#*" data-semver="0.2.15" src="//rawgit.com/angular-ui/ui-router/0.2.15/release/angular-ui-router.js"></script>
<script type="text/javascript" src="app.js"></script>
</head>
<body ng-controller="LoginController as lgCtrl">
<h1>This page does not use ui.router</h1>
Login
</body>
</html>
The page with ui-view tag is inside a manage folder:
manage/home.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://code.angularjs.org/1.3.16/angular.js" data-semver="1.3.16" data-require="angular.js#1.3.16"></script>
<script data-require="ui-router#*" data-semver="0.2.15" src="//rawgit.com/angular-ui/ui-router/0.2.15/release/angular-ui-router.js"></script>
<script type="text/javascript" src="../app.js"></script>
</head>
<body ng-controller="EventsController as evtCtlr">
<h1>Hello manage/home.html</h1>
<div ui-view></div>
</body>
</html>
The templateUrl page to be inserted is:
manage/events.html
<div ng-controller="EventsController as evtCtrl">
<h3>Events Page</h3>
<div>Some user email</div>
</div>
app.js
'use strict';
(function () {
var app = angular.module('app', ['ui.router']);
/**
* Configuration for ui-router module. Handles navigation based on app states.
*/
app.config(function ($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise('events');
$stateProvider
.state('events', {
url: '/events',
views:{
'#manage/home':{
templateUrl: 'manage/events.html'
}
}
});
});
app.controller('LoginController', ['$scope','$window', '$state',
function($scope, $window, $state){
$scope.goToEvents = function(){
console.log('trying to load events');
//this call doesn't work, 404 - It should?? -->> see reference
//https://github.com/angular-ui/ui-router/wiki/URL-Routing
$window.location.href = 'manage/home.html/events';
//don't work
//$state.transitionTo('events');
//also don't work
//$state.go('events');
};
}]);
app.controller('EventsController', [function(){
console.log('EventsController');
}]);
})();
I have created a plunker that represents this:
http://plnkr.co/edit/7UQTlMRQBMXGaRdHlPfs?p=preview
I have tried different ways of moving from the first non ui.router page but none worked so far.
What's the best way of doing this?
Firstly , do not inject $state as dependency in the LoginController as the view related to this controller isn't an UI route. Adding the $state dependency causes the loop that you are seeing in your example as UI-Router then considers this view a route. As no state matches this route , it tries to load the default state , whose template has a relative URL , which then looks it up inside wrong directory of Plunkr , which causes 404 error.
Secondly , the URL to redirect should via location.href should have a hash otherwise it will also give 404
The code for the LoginController
app.controller('LoginController', ['$scope', '$window',
function($scope, $window) {
$scope.goToEvents = function() {
//Do Something
$window.location.href = 'manage/home.html#/events';
};
}
]);
Check the working example at http://plnkr.co/edit/K2iBYu?p=preview

ng-Route is not loading the view, a blank screen is displayed without any errors

I am trying to creae an application in angular using ng-route but i cannot get it to work.
I did search the issue and tried suggestions like to move my ng-app to but nothing seems to work.
I have added a plunker link below
http://plnkr.co/edit/a8VIRzloIMqANK4f8YXb?p=preview
Can someone help
adding the code here too
index html
<!DOCTYPE html>
<html >
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap-theme.min.css">
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.5/angular.min.js"></script>
<script type="text/javascript" src="dist/ng-table.min.js"></script>
<link rel="stylesheet" href="dist/ng-table.min.css">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.3.15/angular-route.min.js"></script>
<link href="main.css" rel="stylesheet" />
<script type="text/javascript" src="app.js"></script>
<script type="text/javascript" src="DemoCtrl.js"></script>
</head>
<body ng-controller="DemoCtrl" ng-app="stockApp">
<header>
<div class="blog-masthead">
<div class="container">
<nav class="blog-nav">
<h1 class="stockHeader">Stock App</h1>
<a class="blog-nav-item pull-right" href="#/">Login</a>
<a class="blog-nav-item pull-right" href="#/stock">Stock</a>
<a class="blog-nav-item active pull-right" href="#/addTools">Add Tools</a>
</nav>
</div>
</div>
</header>
<div ng-view></div>
</body>
</html>
app.js
var sampleApp = angular.module('stockApp', ['ngRoute']);
sampleApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'login.html',
controller: 'DemoCtrl'
}).
when('/stock', {
templateUrl: 'stockStatus.html',
controller: 'DemoCtrl'
}).
when('/addTools', {
templateUrl: 'addTools.html',
controller: 'DemoCtrl'
}).
otherwise({
redirectTo: '/'
});
}]);
DemoCtrl.js
var app = angular.module('stockApp', ['ngTable']).
controller('DemoCtrl', function($scope) {
$scope.stock="In Stock!"
})
other than these have 3 partials.
See this fork of your original plunker where the code segments below have been updated: http://plnkr.co/edit/91XYMEC85Shgu6kQSrty?p=preview
// DemoCtrl.js
var app = angular.module('controllers', []).
controller('DemoCtrl', function($scope) {
$scope.stock="In Stock!"
})
// app.js
var sampleApp = angular.module('stockApp', ['ngRoute', 'controllers']);
First, your controller code was re-initializing the stockApp module by passing in dependencies. If you need separate depedencies for your controllers, create them as a separate module and make your app dependent on that module.
Second, I updated the versions of angular and angular JS. Conflicting versions can cause issues as per this prior answer: Failed to instantiate module [$injector:unpr] Unknown provider: $routeProvider.
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular.min.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.14/angular-route.js"></script>
One additional thing to check on... make sure you're loading your angular js files (controllers, services, factories, etc) in the correct order. For example, if a controller uses a service, the service needs to be loaded into the DOM before the controller.
Additionally, make sure that none of your services or factories are re-initializing the app. Your code should NOT look like this:
angular.module('app', [])
.service('TrxnService', function () {
//code here
})
But instead, it should look like this (without the brackets)...
angular.module('app')
.service('TrxnService', function () {
//code here
})
NOTE FOR NEWBIES: replace 'app' with whatever you named your app in your top level module declaration.

How to inherit page appearance?

I have a few pages in my website.
I have a general frame for my website: Top, bottom, and general css are the same for all pages.
What is the convenient way to share the frame between all pages, so that they all look the same.
The AngularJS way to achieve this is by the use of ng-view and routes.
For this, you must include the angular-route file and inject ngRoute in your app. Follow the example:
index.html
<!DOCTYPE html>
<html ata-ng-app="myApp">
<head>
<meta charset="utf-8" />
<title>My App</title>
</head>
<body>
<header><h1> Header for all pages </h1></header>
<div data-ng-view></div> <!-- your files will be rendered here -->
<footer>...</footer>
<script src="path/to/angular.min.js"></script>
<script src="path/to/angular-route.min.js"></script>
<script src="path/to/app.js"></script>
</body>
</html>
app.js
angular.module('myApp', ['ngRoute'])
.controller('PageCtrl', ['$scope', function($scope) {
$scope.title = "The Title";
}])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider.
when("/", {
templateUrl: "path/to/page.html",
controller: "PageCtrl"
}).
}]);
page.html
<h3> {{ scope.title }} </h3>

Cant integrate facebook login to angular app using ngFacebook

Somehow I am not able to integrate facebook Login to my angularjs app, though I feel I am just loosing a minor mistake which I cant point out and thus you geeks might be sureshot help!
I have used this plunker example:
Following the above code same as what has been mentioned in plunker, below are y files.
my app.js {which has nothing but routing info, ngFacebook module I have injected in controller.js}
'use strict';
// Declare app level module which depends on filters, and services
angular.module('ngdemo', ['ngdemo.filters', '$strap.directives', 'ngdemo.services', 'ngdemo.directives', 'ngdemo.controllers']).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/view5', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl4'});
$routeProvider.when('/view1', {templateUrl: 'modulepages/home.html', controller: 'MyCtrl1'});
$routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
$routeProvider.when('/view4', {templateUrl: 'modulepages/bizregistration.html', controller: 'MyCtrl3'});
$routeProvider.when('/view6', {templateUrl: 'partials/modalcontent.html', controller: 'MyCtrl5'});
$routeProvider.otherwise({redirectTo: '/view5'});
}]);
And this is my Controller.js which has the heart of ngFacebook Integration.
'use strict';
/* Controllers */
var app = angular.module('ngdemo.controllers', ['ngResource', 'ngFacebook'])
.config([ '$facebookProvider', function( $facebookProvider ) {
alert("am i here?");
$facebookProvider.setAppId('239661002870669');
}]);
// Clear browser cache (in development mode)
//
// http://stackoverflow.com/questions/14718826/angularjs-disable-partial-caching-on-dev-machine
app.run(function ($rootScope, $templateCache) {
(function(){
// If we've already installed the SDK, we're done
if (document.getElementById('facebook-jssdk')) {return;}
// Get the first script element, which we'll use to find the parent node
var firstScriptElement = document.getElementsByTagName('script')[0];
// Create a new script element and set its id
var facebookJS = document.createElement('script');
facebookJS.id = 'facebook-jssdk';
// Set the new script's source to the source of the Facebook JS SDK
facebookJS.src = '//connect.facebook.net/en_US/all.js';
// Insert the Facebook JS SDK into the DOM
firstScriptElement.parentNode.insertBefore(facebookJS, firstScriptElement);
}());
$rootScope.$on('$viewContentLoaded', function () {
$templateCache.removeAll();
});
});
app.controller('DemoCtrl', ['$scope', '$facebook', function ($scope, $facebook) {
alert("I am here out");
$scope.isLoggedIn = false;
$scope.login = function() {
$facebook.login().then(function() {
refresh();
});
}
function refresh() {
$facebook.api("/me").then(
function(response) {
$scope.welcomeMsg = "Welcome " + response.name;
$scope.isLoggedIn = true;
},
function(err) {
$scope.welcomeMsg = "Please log in";
});
}
refresh();
}]);
and that's my index.html
<!DOCTYPE html>
<html ng-app="ngdemo" lang="en">
<head>
<meta charset="utf-8">
<title>You local needs are just a pingle away - pingle.com</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/app.css"/>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css" rel="stylesheet">
</head>
<body ng-controller="DemoCtrl" bgcolor="#e8e8e8">
<div class="container">
<h4>
{{welcomeMsg}}
</h4>
<button type="button" ng-click="login()" ng-hide="isLoggedIn" class="btn btn-default navbar-btn">
Login
</button>
</div>
<div id="fb-root">
</div>
<div ng-view>
</div>
<script src="lib/angular/angular.js"></script>
<script src="lib/angular/angular-resource.js"></script>
<script src="lib/angular/angular-strap.js"></script>
<script src="js/app.js"></script>
<script src="js/services.js"></script>
<script src="js/controllers.js"></script>
<script src="js/filters.js"></script>
<script src="js/directives.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.7.0.js">
</script>
<script src="//rawgithub.com/GoDisco/ngFacebook/master/ngFacebook.js"></script>
</body>
</html>
Could you please help where the problem is, it will be a great help and it is the important part of my application.
I just copied/pasted your code in my IDE and tested it.
I had to remove some things to simplify the testing.
E.g. remove filters, directives, services and also the config for the routeprovider.
I also removed angular-strap. I updated the facebook app id to an ID of an app I own...
If you remove everything you can get it working, then you can gradually add what you need, like routing, angular-strap etc. maybe one of those creates problems...
The code you provided (cleaned with all unnecessary stuff) just worked fine for the facebook login, like the plunker code...
At the moment of writing, if you do not specify the API Facebook version you may get an error in the console, thus I specify it like this:
angular.module('app')
.config(function ($facebookProvider) {
$facebookProvider.setAppId(facebookAppId);
$facebookProvider.setCustomInit({
version: 'v2.1'
});
$facebookProvider.setPermissions('email');
});
Actually I think this question can be closed because the code provided was incomplete and needed some effort, like removing all the unneded stuff as I mentioned...

ng view not working with custom directive

I have recently started learning angularJS and ran into an issue with ng-view directive. Apologies if this question is too naive.
This is my index.html file. As you can see, I am using ng-view directive to abstract out some html code from index.html file.
<!doctype html>
<html lang="en" ng-app="phonecat">
<head>
<meta charset="utf-8">
<title>My first app!</title>
<script src="lib/angular/angular.js"></script>
<script src="js/app.js"></script>
<script src="js/directives.js"> </script>
<script src="js/controllers.js"></script>
</head>
<body>
<div ng-view></div>
</body>
</html>
This is my app.js file. I am using the same partial template for all the urls.
angular.module('phonecat', []).
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/phones', {templateUrl: 'partials/searchbox.html', controller: PhoneListCtrl}).
otherwise({templateUrl: 'partials/searchbox.html', controller: PhoneListCtrl});
}]);
and this is my searchbox.html
<div id="container">
<input type="text" name="s" id="s" float-up="{perspective: '100px', x: '150%'}"/>
</div>
and finally this is my directives.js file:
'use strict';
var myAppModule = angular.module('phonecat', []);
myAppModule.directive('floatUp', function() {
return {
// Restrict it to be an attribute in this case
restrict: 'A',
// responsible for registering DOM listeners as well as updating the DOM
link: function($scope, element, attrs) {
console.log("test successful");
}
};
});
When I run this in the browser, the link function of my floatUp directive is never invoked.
When I see the rendered html of my index.html page, I get this (Note that ng-view didn't substitute the searchbox html):
<!DOCTYPE html>
<html class="ng-scope" lang="en" ng-app="phonecat">
<head>
<meta charset="utf-8">
<title>My first app!</title>
<script src="lib/angular/angular.js">
<style type="text/css">
<script src="js/app.js">
<script src="js/directives.js">
</head>
<body>
<div ng-view=""></div>
</body>
</html>
Other observations:
When I remove the directives.js from the index.html file ng-view works perfect and searchbox shows up fine.
When I copy paste the searchbox.html content to the index.html file, the link function is invoked properly.
Is this a known issue? Do custom directives mess up with ng-view and make it futile. I assure you I did extensive googling before posting my question here but couldn't find any appropriate answer.
Move this line from the directives.js
var myAppModule = angular.module('phonecat', []);
to the top of app.js
That way you're always working with the same angular module instance instead of creating new instances of it.
All your controllers, directives, and configs will then be myApModule.controller (or .config, or .directive)
Also in the app.js the references to controller in the routes should be strings controller: 'PhoneListCtrl' as PhoneListCtrl is not defined yet.
Your controllers.js wasn't provided but could look something like this:
myAppModule.controller('PhoneListCtrl', ['$scope', function($scope) {
//Controller code here
}]);
apps.js would now look like this:
myAppModule.
config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/phones', {templateUrl: 'partials/searchbox.html', controller: 'PhoneListCtrl'}).
otherwise({templateUrl: 'partials/searchbox.html', controller: 'PhoneListCtrl'});
}]);

Resources