How to access a variable declared in the controller from the view? - angularjs

I am pretty new to AngularJS. I have trouble understanding how to access variables declared in the controller from the view. For example, in the code below I am not able to access the variable filePath
HTML
<div ng-controller = "buttonViewCtrl as buttonCtrl">
{{ buttonCtrl.filePath }}
</div>
JS
.controller('buttonViewCtrl', ['$scope', '$location', function($scope, $location) {
$scope.filePath = '';
$scope.nav = function() {
$scope.filePath = "Logged In";
};
I am providing my entire application below for context:
index.html:
<!DOCTYPE html>
<html lang="en" ng-app="myApp" class="no-js">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>My AngularJS App</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="bower_components/html5-boilerplate/dist/css/normalize.css">
<link rel="stylesheet" href="bower_components/html5-boilerplate/dist/css/main.css">
<link rel="stylesheet" href="app.css">
<script src="bower_components/html5-boilerplate/dist/js/vendor/modernizr-2.8.3.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"/>
<link rel="shortcut icon" href="images/favicon.ico" />
<link rel="stylesheet" href="css/anchour/anchour.css"/>
</head>
<body>
<div ng-view></div>
<div>Angular seed app: v<span app-version></span></div>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-route/angular-route.js"></script>
<script src="app.js"></script>
<script src="view1/view1.js"></script>
<script src="view2/view2.js"></script>
<script src="buttonView/buttonView.js"></script>
<script src="components/version/version.js"></script>
<script src="components/version/version-directive.js"></script>
<script src="components/version/interpolate-filter.js"></script>
</body>
</html>
app.js:
'use strict';
angular.module('myApp', [
'ngRoute',
'myApp.view1',
'myApp.view2',
'myApp.version'
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider.otherwise({redirectTo: '/view1'});
}]);
view1.html:
<div class="squirrel">
<div class="logo"></div>
<cite>Every brand has a story.</cite>
<h2> <a>Watch the video </a></h2>
<aside> → </aside>
<button type="button" class="btn btn-default btn-lg navButton" aria-label="Center Align" ng-controller = "buttonViewCtrl" ng-click="go('/buttonView')">
<span class="glyphicon glyphicon-align-justify" aria-hidden="true"></span>
</button>
<div id = "arrow">
<img src = "images/pointer.png" alt = "arrow">
</div>
</div>
<div class = "panda">
<button type="button" class="btn btn-default btn-lg work"> SEE OUR WORK </button>
</div>
<div class = "experience">
<h1> Our team builds great brands and experiences. </h1>
<button type="button" class="btn btn-default btn-lg team"> MEET THE TEAM </button>
</div>
<section class = "about">
<h5> WHAT ARE WE? </h5>
<h2> Anchour is a branding agency based in Maine. </h3>
<p> We weave together creative solutions to build personal brands and experiences. We work closely with your brand to understand your needs and create solutions that produce real results. By integrating the power of identity, digital, and sensory design, we bring new life to brands everywhere.
</p>
</section>
<div class = "goodWork">
<div class = "spotlight">
<h3> Spotlight: Amanda Brill of Las Vegas </h3>
<p> Amanda Brill is a Designer at Anchour. Fueled by the purpose of helping others, she works to bring the identity of a brand to life through a creative and intensive design process. to help brands effectively communicate who they she works to bring the identity of a brand to life through a creative... </p>
<footer> Read More </footer>
</div>
<div class = "spotlight">
<h3> Spotlight: Amanda Brill of California </h3>
<p> Amanda Brill is a Designer at Anchour. Fueled by the purpose of helping others, she works to bring the identity of a brand to life through a creative and intensive design process. Her goal is to use design as a way to help brands effectively communicate who they sponsor and supporter Fueled by the purpose of.. </p>
<footer> Read More </footer>
</div>
<div class = "spotlight">
<h3> Varney Agency: Protecting What You </h3>
<p> Anchour produced Varney Agencys latest spot featuring Matt Albrecht, owner of River Drive. Working with companies from all around the world, River Drive buys, sells, reconditions and recycles reconditions and ecycles owner of used. River Drive buys, sells Varney Agencys latest spot featuring Matt Albrecht.</p>
<footer> Read More </footer>
</div>
<div class = "spotlight">
<h3> Announcing support of Not Here </h3>
<p> This week is Human Trafficking Awareness Week, so it’s great timing to share how proud we are to be a sponsor and supporter of Not Here latest spot featuring Matt Albrecht, reconditions and recycles owner of River Drive. Working with companies from all around the,a River Drive buys, sells.... </p>
<footer> Read More </footer>
</div>
</div>
<div class = "start">
<h2 id = "startWork"> Want to work with us? </h2>
<button type="button" class="btn btn-default btn-lg"> Get Started → </button>
</div>
<div id = "end">
<footer>
Home
About us
Our Team
Blog
Services
Portfolio
Contact
Sitemap
</footer>
</div>
view1.js:
'use strict';
angular.module('myApp.view1', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/view1', {
templateUrl: 'view1/view1.html',
controller: 'View1Ctrl'
}).
when('/buttonView', {
templateUrl: 'buttonView/buttonView.html',
controller: 'buttonViewCtrl'
});
}])
.controller('View1Ctrl', [ '$scope', function($scope) {
$scope.name = '';
$scope.names = [{name:"Chris"}, {name:"Calvin"}];
$scope.addName = function() {
$scope.names.push( {'name':$scope.name} );
$scope.name = '';
};
}])
.controller('buttonViewCtrl', ['$scope', '$location', function($scope, $location) {
$scope.go = function( path ) {
$location.path( path );
};
}]);
view2.html
<p> What is going on </p>
view2.js:
'use strict';
angular.module('myApp.view2', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view2', {
templateUrl: 'view2/view2.html',
controller: 'View2Ctrl'
});
}])
.controller('View2Ctrl', [function() {
}]);
buttonView.html
Home
About us
Why
buttonView.js
'use strict';
angular.module('myApp.buttonView', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/buttonView', {
templateUrl: 'buttonView/buttonView.html'
});
}])

When you use $scope for set data u can use it directly
angular
.module('app')
.controller('buttonViewCtrl', ['$scope', '$location', function($scope, $location) {
$scope.filePath = '';
$scope.nav = function() {
$scope.filePath = "Logged In";
};
<div ng-controller = "buttonViewCtrl">
{{ filePath }}
</div>
If u want to use controllerAs syntax (better way) it should looks like
angular
.module('app')
.controller('buttonViewCtrl', ['$scope', '$location', function($scope, $location) {
var mv = this;
mv.filePath = '';
mv.nav = function() {
mv.filePath = "Logged In";
};
<div ng-controller = "buttonViewCtrl as buttonCtrl">
{{ buttonCtrl.filePath }}
</div>

your view is configured for controller alias way ,, yet your controller is configured for $scope way
so to keep the view with the controller alias way ,, you need to change your controller to use this structure instead of the current one
this.filePath = "Logged In";
but if you want to kepp the scope way ,, then there is no need for the controller alias in the view ,, change it to this
<div ng-controller = "buttonViewCtrl">
{{filePath}}
</div>
notice that we access $scope variable directly without any accessor (like controller alias)

Related

When clicking very quickly on Angularjs app page doesn't load

FYI - I am very new to Angular...not my code mostly from tutorial on Lynda which I am playing with.
I noticed when I am doing a type of "pagination" where I am showing different elements from a data.json file, the page doesn't load if I click page back anchor links too quickly to show the next or previous item. The culprit begins somewhere as a result of the anchor tags here (details.html file) / in the controller of details. I am wondering if it's async/await not being used issue.
<div class="container">
<div class="row">
<div class="col-12 mt-3">
<div class="card">
<div class="card-header d-flex align-items-start justify-content-between">
<h1 class="card-title my-0">{{artists[whichItem].name}}</h1>
<nav class="btn-group">
<a class="btn btn-sm btn-secondary"
href="#/details/{{prevItem}}"><</a>
<a class="btn btn-sm btn-secondary"
href="#/">•Home</a>
<a class="btn btn-sm btn-secondary"
href="#/details/{{nextItem}}">></a>
</nav>
</div>
<div class="card-body"
ng-model="artists">
<h4 class="card-title text-dark mt-0">{{artists[whichItem].reknown}}</h4>
<img class="float-left mr-2 rounded"
ng-src="images/{{artists[whichItem].shortname}}_tn.jpg"
alt="Photo of {{artists[whichItem].name}}">
<div class="card-text text-secondary">{{artists[whichItem].bio}}</div>
</div>
</div>
</div>
</div>
</div>
In the meantime - By searching different things online I added a
.otherwise({
redirectTo: '/'
});
a redirect so something shows up. It'd be great if someone can please help explain what's causing that and how to fix it. I am posting the code below. I also added console.logs to help me debug in my controller, but I was not successful.
My smaller controller - (controllers.js):
var myControllers = angular.module('myControllers', []);
myControllers.controller('SearchController', function MyController($scope, $http) {
$scope.sortArtistBy = 'name';
$http.get('js/data.json').then(
(response) => $scope.artists = response.data
);
});
myControllers.controller('DetailsController', function MyController($scope, $http, $routeParams) {
$http.get('js/data.json').then(
function(response) {
$scope.artists = response.data
$scope.whichItem = $routeParams.itemId;
if($routeParams.itemId > 0){
$scope.prevItem = Number($routeParams.itemId) - 1;
console.log("I am going to 18")
} else {
console.log("I am going to 20")
$scope.prevItem = $scope.artists.length - 1;
}
if($routeParams.itemId < $scope.artists.length - 1){
console.log("I am going to 25")
$scope.nextItem = Number($routeParams.itemId) + 1;
} else {
console.log("I am going to 28")
$scope.nextItem = 0;
}
}
);
});
My main app controller (app.js):
var myApp = angular.module('myApp', [
'ngRoute',
'myControllers'
]);
myApp.config(['$routeProvider', function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: 'js/partials/search.html',
controller: 'SearchController'
})
.when('/details/:itemId', {
templateUrl: 'js/partials/details.html',
controller: 'DetailsController'
})
.otherwise({
redirectTo: '/'
});
}]);
My (index.html) file:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<meta charset="utf-8">
<title>AngularJS</title>
<meta name="viewport" content="width=device-width">
<link rel="stylesheet" href="lib/bootstrap/bootstrap.min.css">
<link rel="stylesheet" href="css/style.css">
<script src="lib/angular/angular.min.js"></script>
<script src="lib/angular/angular-route.min.js"></script>
<script src="js/app.js"></script>
<script src="js/controllers.js"></script>
</head>
<body class="bg-secondary">
<div ng-view></div>
<script src="lib/jquery/jquery.min.js"></script>
<script src="lib/bootstrap/popper.min.js"></script>
<script src="lib/bootstrap/bootstrap.min.js"></script>
</body>
</html>
One approach is to cache the data in a service:
app.service("dataService", function($http) {
var cache;
this.get = () => {
cache = cache || $http.get('js/data.json');
return cache;
};
})
Then in the controller:
app.controller('DetailsController', function MyController($scope, dataService, $routeParams) {
dataService().then(
function(response) {
$scope.artists = response.data
$scope.whichItem = $routeParams.itemId;
//...
}
);
});
By caching the $http promise, the app avoids repeating identical requests to the server.

Passing Data between state Providers in angular

Im looking to pass data between 2 controllers in Angular, Below is code i started
There are 2 views one with input field and other with a link.
when i click on link in the second view i should be able to set a state and state data should be populated in input field in first field.
I tried several approaches but im missing something.
Can someone help me here
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>Hello AngularJS</title>
<script data-require="angular.js#1.2.10" data-semver="1.2.10" src="http://code.angularjs.org/1.2.10/angular.min.js"></script>
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js"></script>
<script type="text/javascript">
var myApp = angular.module('myApp', ['ui.router']);
myApp.config(['$stateProvider','$stateProvider', '$urlRouterProvider', function ($stateProvider,$urlRouterProvider) {
var addBook = {
name: 'addBook',
url: '/addBook',
template: '<h2>Add A book</h2> Data from View <input type="text" ng-model={{input-text}}>' ,
data:""
},
viewBookv = {
name: 'viewBookv',
url: '/viewBook',
template: '<h2>View A book</h2><span class="glyphicon glyphicon-edit">Edit</span> ' ,
};
$stateProvider.state(addBook, "controller: editUserCtrl");
$stateProvider.state(viewBookv, "controller: editUserCtrl");
}])
myApp.controller('editUserCtrl', function($scope, $stateParams) {
$scope.paramOne = $stateParams.data;
$scope.edit = function () {
event.preventDefault();
$state.go("addBook");
}
})
myApp.controller('mainController',function($scope, $rootScope, $state,$window){
$scope.addBook=function(){
$state.go("addBook");
};
$scope.viewbookls= function(){
$state.go("viewBookv");
};
})
</script>
</head>
<body>
<div class="container">
<div class="col">
<div class="col-md-3" ng-controller="mainController">
<ul class="nav">
<li> View Book </li>
<li> Add Book </li>
</ul>
</div>
<div class="col-md-9">
<div ui-view></div>
</div>
</div>
</div>
</body>
</html>
Typically in angular the way to share state between controllers is using a service. So the way it's usually set up is to setup a service then import that service into the relevant controllers, and that data gets shared between them. I've modified your example above to follow this pattern(I'm not quite sure what you were trying to do)
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>Hello AngularJS</title>
<script data-require="angular.js#1.2.10" data-semver="1.2.10" src="http://code.angularjs.org/1.2.10/angular.min.js"></script>
<script src="http://angular-ui.github.io/ui-router/release/angular-ui-router.min.js"></script>
<script type="text/javascript">
var myApp = angular.module('myApp', ['ui.router']);
myApp.config(['$stateProvider', '$urlRouterProvider', function ($stateProvider,$urlRouterProvider) {
var addBook = {
name: 'addBook',
url: '/addBook',
template: '<h2>Add A book</h2> Data from View <button ng-click="updateBook()">Update</button> <input type="text" ng-model="inputText">' ,
controller: "addBookCtrl",
data:""
},
viewBookv = {
name: 'viewBooks',
url: '/viewBook',
template: '<h2>View A book</h2><div ng-repeat="book in bookList">{{book}}</div>',
controller: "viewBookCtrl",
};
$stateProvider.state('addBook', addBook);
$stateProvider.state('viewBooks', viewBookv);
}])
myApp.controller('addBookCtrl', function($scope, bookService) {
$scope.updateBook = function(){
console.log( $scope.inputText)
bookService.books.push($scope.inputText);
}
})
myApp.controller('viewBookCtrl', function($scope, bookService) {
$scope.bookList = bookService.books
})
myApp.factory('bookService', function() {
var bookService = {};
bookService.books = [];
return bookService;
});
myApp.controller('mainController',function($scope, $rootScope, $state,$window){
$scope.addBook=function(){
$state.go("addBook");
};
$scope.viewbookls= function(){
$state.go("viewBooks");
};
})
</script>
</head>
<body>
<div class="container">
<div class="col">
<div class="col-md-3" ng-controller="mainController">
<ul class="nav">
<li> View Book </li>
<li> Add Book </li>
</ul>
</div>
<div class="col-md-9">
<div ui-view></div>
</div>
</div>
</div>
</body>
</html>
What this example does, is in the text box for add book, you type in the name (then click update), this appends it to an array so every time you do it you'll get a new element on that array. From there head over to the view books page, and you'll see all the different things you typed in.

Angularjs - $routerProvider's 'when' function and 'templateUrl' navigate to 'wrong' path?

My dir's structure is like:
---/public
|
---index.html
---shop.html
|
---/js
|
---index.js
---index_controller.js
---/lib
---/css
---/plugins
|
---...
my index.html:
<!doctype html>
<html class="signin no-js" lang="">
<head>
<meta charset="utf-8">
<meta name="description" content="Flat, Clean, Responsive, application admin template built with bootstrap 3">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<title>Index</title>
<link rel="stylesheet" href="bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="css/font-awesome.css">
<link rel="stylesheet" href="css/themify-icons.css">
<link rel="stylesheet" href="css/animate.min.css">
<link rel="stylesheet" href="css/skins/palette.css">
<link rel="stylesheet" href="css/fonts/font.css">
<link rel="stylesheet" href="css/main.css">
<script src="js/lib/angular/angular.js"></script>
<script src="js/lib/angular/angular.min.js"></script>
<script src="js/lib/angular/angular-route.js"></script>
<script src="js/lib/angular/angular-route.min.js"></script>
<script src="js/index_controller.js"></script>
<script src="js/index.js"></script>
<script src="plugins/modernizr.js"></script>
</head>
<body class="bg-primary" ng-app="myApp.index">
<div class="cover" style="background-image: url(img/cover3.jpg)"></div>
<div class="overlay bg-primary"></div>
<div class="center-wrapper">
<div class="center-content">
<div class="row">
<div class="col-xs-10 col-xs-offset-1 col-sm-6 col-sm-offset-3 col-md-4 col-md-offset-4">
<section class="panel bg-white no-b">
<ul class="switcher-dash-action">
<li class="active">Index</li>
</ul>
<div class="p15" ng-controller="IndexCtrl">
<form role="form" >
<div >
<button class="btn btn-primary btn-lg btn-block" ng-click='testRoute()'>
TestRoute
</button>
</div>
</form>
</div>
</section>
<p class="text-center">
Copyright ©
<span id="year" class="mr5"></span>
</p>
</div>
</div>
</div>
</div>
<script type="text/javascript">
var el = document.getElementById("year"),
year = (new Date().getFullYear());
el.innerHTML = year;
</script>
</body>
</html>
And shop.html renders the following: (only for test use):
SHOP
And index_controller.js is :
function IndexCtrl($scope, $http, $location, $route, $window) {
$scope.testRoute = function() {
console.log(">>>TestRoute>>>");
$location.url('/shop');
}
}
function ShopCtrl() {
console.log("ShopCtrl");
}
And index.js:
'use strict';
//Angular-js
var module = angular.module('myApp.index', ['ngRoute']);
module.config(['$routeProvider', function($routeProvider) {
$routeProvider.
when('/shop', {templateUrl: 'shop.html', controller: ShopCtrl
});
}]);
/*My Controllers*/
module.
controller('IndexCtrl', ['$scope', '$http', '$location', '$route', '$window', IndexCtrl]);
module.
run([
'$rootScope', '$location',
function($rootScope, $location) {
$rootScope.$on('$routeChangeStart', function(event, next, current) {
var nextTemplate = next.templateUrl;
var nextController = next.controller;
console.log("location.path:" + $location.path());
console.log('Template Starting to leave %s to go to %s\n', "", nextTemplate);
console.log('Controller Starting to leave %s to go to %s\n', "", nextController);
});
}
]);
And when I type "http://localhost:6001/index.html" in Chrome's address bar, it renders:
After clicking Test Route button, it changes to:
Only the url address changes, and it seems strange:
"http://localhost:6001/index.html#/shop"
Whereas I need
"http://localhost:6001/shop"
Chrome's console shows:
My problem is: how to render shop.html and how to navigate to /guoguo path properly, using code like:
$routeProvider.when('/shop', {templateUrl: 'shop.html', controller: ShopCtrl
});
I am pretty new to Angular. Maybe I am not thinking in the angularjs approach. Thanks for your points.
It is a mix of issues for your .html# being shown. Try this.
1: Add in the first line of head tags
<head><base href="/">
...
</head>`
2: Use this $locationProvider.html5Mode(true);
app.config(function($routeProvider,$locationProvider){
$routeProvider
.when('/',{
templateUrl: 'views/home.html',
controller:'homeCtrl'
})
.when('/about',{
templateUrl: 'views/about.html',
controller:'aboutCtrl'
})
.otherwise({
redirectTo: '/home'
});
$locationProvider.html5Mode(true);
});
This should remove the # from the page. But in your server make index.html as the default file serving for the path http://localhost:6001/ then it will load http://localhost:6001/index.html as http://localhost:6001/
I finaly get to know that AngularJS is a SPA(Single Page App) based framwork. If I simply jump to another html, the page will load another ng-app, which has no relation to origin app(the bootstrap has been restarted).
What solution I take is to use ng-view inside the index html. It allows to load different ng-view(which is in '<div></div>' from other html file), and config the routeProvider by declaring template url and controller.
I will paste the complete code later, thanks for you all !!!

Unable to inject service in the controller

I have done this when the service and controller are in a single file (usually, app.js) and it works without any issues.
Now, I have the controllers and services organized in different files and the respective folders. I need to inject 1 particular service in a controller but I am running into an error.
This is a simple angular app that I am working on that has a way to manage your YouTube favorite videos. I am getting the error on the add page. Just click on add button to see the error.
Equivalent Plunker
Here is what I have so far:
index.html
<!doctype html>
<html ng-app="youtube-favorites">
<head>
<title>My YouTube Favorites</title>
<link rel="stylesheet" type="text/css" href="bower_components/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" type="text/css" href="css/custom.css" />
</head>
<body>
<div class="container">
<div class="row">
<div class="col-md-12" style="border: 1px solid red;">
<div ui-view></div>
</div>
</div>
</div>
<script src="bower_components/angular/angular.js"></script>
<script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.min.js"></script>
<script src="bower_components/angular-ui-router/release/angular-ui-router.min.js"></script>
<script src="app.js"></script>
<script src="services/add.js"></script>
<script src="controllers/home.js"></script>
<script src="controllers/add.js"></script>
</body>
</html>
app.js
angular.module('youtube-favorites', ['ui.bootstrap', 'ui.router'])
.config(['$stateProvider', '$urlRouterProvider',
function($stateProvider, $urlRouterProvider) {
// For any unmatched url, redirect to /home
$urlRouterProvider.otherwise('/home');
// Now set up the states
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'views/home.html',
controller: 'homeController'
})
.state('add', {
url: '/add',
templateUrl: 'views/add.html',
controller: 'addController'
});
}
]);
Controller - add.js
angular.module('youtube-favorites')
.controller('addController', ['$scope', '$log', 'addService',
function($scope, $log, addService) {
$log.info('add');
$scope.addFavorite = function() {
addService.addFavorite($scope.title, $scope.youtubeUrl)
$log.info('title', $scope.title);
$log.info('youtubeUrl', $scope.youtubeUrl);
};
}
]);
Service - add.js
angular.module('youtube-favorites', [])
.service('addService', ['$scope', '$log', '$q', '$window',
function($scope, $log, $q, $window) {
$log.info('add service called');
this.addFavorite = function(title, url) {
$log.info('title', title);
$log.info('url', url);
$window.localStorage.setItem('youtubeFavorites', angular.toJson({
title: title,
url: url
}));
return true;
};
}
]);
View - add.html
<form name="addForm" ng-submit='addFavorite()' novalidate>
<div class="form-group">
<label for="title">Title</label>
<input type="text" name="title" class="form-control" placeholder="Awesome video!" aria-describedby="title" ng-model="title" required />
<!-- <p ng-show="addForm.title.$error.required" class="help-block">Please enter the title.</p> -->
</div>
<div class="form-group">
<label for="youtubeUrl">YouTube <em>embed</em> URL</label>
<input type="text" name="youtubeUrl" class="form-control" placeholder="https://www.youtube.com/embed/someID" aria-describedby="youtubeUrl" ng-model="youtubeUrl" required />
<!-- <p ng-show="addForm.youtubeUrl.$error.required" class="help-block">Please enter the URL.</p> -->
</div>
<div class="form-group">
<button class="btn btn-default grey" type="submit">Submit</button>
</div>
</form>
Here is the error that I am getting:
Pretty sure that I am not injecting the service correctly.
I did try adding the service as a dependency to the app module as per below, but still giving an error.
angular.module('youtube-favorites', ['ui.bootstrap', 'ui.router', 'youtube-favorites.addService'])....
How do I fix this?
In your addService, change this:
angular.module('youtube-favorites', [])
to this:
angular.module('youtube-favorites')
You are effectively creating a new module with the same name when you include the empty [].
Also, you should be passing in $rootScope to your service because $scope is only available to controllers.
You can't inject $scope into a service. You can inject $rootScope, but $scope is a thing that gets injected at the controller level.
Take a look at this stack post for a little more detail.

Unable to change the location after calling controller function

I have read and tried applying all of the approaches I can find on SO but none of them work.
I just basically want to load a different view once the user logs in:
myApp.controller('LoginCtrl', ['$scope', '$rootScope', '$location', function($scope, $rootScope, $location) {
$scope.Login = function () {
$location.path('/view1');
// $scope.$apply(); <- error when trying this
};
}]);
Nothing happens. If I try $scope.$apply after changing the location then I get the 'action already in progress' error (http://docs.angularjs.org/error/$rootScope:inprog?p0=$apply)
I have also tried $location.url, etc. Can someone please clue me in on what is happening?
Here is my routing config:
angular.module('myApp', [
'ngRoute',
'myApp.filters',
'myApp.services',
'myApp.directives',
'myApp.controllers'
]).
config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/login', {templateUrl: 'views/login.html', controller: 'LoginCtrl' });
$routeProvider.when('/view1', {templateUrl: 'views/partial1.html', controller: 'MyCtrl1'});
$routeProvider.when('/view2', {templateUrl: 'views/partial2.html', controller: 'MyCtrl2'});
$routeProvider.otherwise({redirectTo: '/login'});
}]);
Index File:
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<title>Foxy Flakes of Steel</title>
<link rel="icon" href="favicon.ico" type="image/x-icon" />
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon" />
<link rel="stylesheet" href="assets/plugins/bootstrap/css/bootstrap.min.css" />
<link rel="stylesheet" href="assets/css/app.css" />
</head>
<body>
<div class="container">
<div class="row" ng-view></div>
</div>
<script src="assets/plugins/jquery/jquery-2.0.3.min.js"></script>
<script src="assets/plugins/bootstrap/js/bootstrap.min.js"></script>
<script src="assets/plugins/angularjs/angular.min.js"></script>
<script src="assets/plugins/angularjs/angular-route.js"></script>
<script src="assets/js/app.js"></script>
<script src="assets/js/services.js"></script>
<script src="assets/js/controllers.js"></script>
<script src="assets/js/filters.js"></script>
<script src="assets/js/directives.js"></script>
</body>
</html>
And here is the login.html view:
<form class="col-md-5 col-md-offset-3">
<div class="rounded-gray">
<div class="row" style="padding: 30px;">
<div class="input-group" style="margin-bottom: 10px;">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<input type="text" placeholder="username" class="form-control" ng-model="username">
</div>
<div class="input-group" style="margin-bottom: 10px;">
<span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
<input type="text" placeholder="password" class="form-control" ng-model="password">
</div>
<div class="row">
Login
</div>
</div>
</div>
</form>
Two tips that I found;
you cannot use $location.path('/view1') during routing is on proress.
it's better to check logged in or not at the level of application stage.
app.run(['$rootScope', '$location', 'Auth', function ($rootScope, $location, Auth) {
$rootScope.$on('$routeChangeStart', function () {
if (!Auth.isLoggedIn()) {
$location.path('/login');
} else {
$location.path('/home');
}
});
}]);
Reference:
1. AngularJS and location.path()
2.
Redirecting to a certain route based on condition
3. AngularJS- Login and Authentication in each route and controller
Your Login link should be a button. The href is overriding your ng-click action.
<button type='button' class='btn btn-primary pull-right' ng-click='Login()'>
Login
</button>
Also, you don't need the semicolon inside ng-click.
(in-line styles are very bad form, btw)
You may use ng-href="#/view1" in your view instead of calling Login method from your controller via ng-click.

Resources