ui-router Main View is rendering thrice and no controller are registering - angularjs

I am trying to create a SPA using angular ui-router with MVC. I am facing three issues.
1.The controllers OfferController.js and OfferCustomizationController.js are not registering.
2.I am getting the errors ' No reference point given for path '.offer', No reference point given for path '.customizations'.
3. Main view is rendering thrice.
I have no clue what am i missing. Please help.
I have included the following files in my Layout.cshtml:
<script src="#Links.Scripts.angular_min_js"></script>
<script src="#Links.Scripts.ProductCatalog.app_js"></script>
<script src="#Links.Scripts.ProductCatalog.service_js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.2.10/angular-ui-router.min.js"></script>
<script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.16/angular-animate.min.js"></script>
I have made two views. Offers And OfferCustomizations. And a main view. Following is my code for the main view:
<div class="inside-data-div" ng-app="ProductCatalog">
#*<div ui-view></div>*#
<div class="col-lg-12">
<div class="row">
<div class="col-sm-8 col-sm-offset-2">
<div id="form-container">
<div class="page-header text-center">
<h2>Create Offer</h2>
<!-- the links to our nested states using relative paths -->
<!-- add the active class if the state matches our ui-sref -->
<div id="status-buttons" class="text-center">
<a ui-sref-active="active" ui-sref=".offer"><span>1</span> Offer Details</a>
<a ui-sref-active="active" ui-sref=".customizations"><span>2</span> Offer Customizations</a>
</div>
</div>
<!-- use ng-submit to catch the form submission and use our Angular function -->
<form id="signup-form" ng-submit="SaveForm()">
<!-- our nested state views will be injected here -->
<div id="form-views" ui-view></div>
</form>
</div>
<!-- show our formData as it is being typed -->
<pre>
{{ formData }}
</pre>
</div>
</div>
</div>
</div>
Following is my code of app js:
var productCatalogApp = angular.module('ProductCatalog', ['ui.router']);
productCatalogApp.value('appName', 'Product Catalog');
productCatalogApp.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
// route to show our basic form (/form)
.state('wizard', {
url: '/wizard',
templateUrl: 'WizardSubForm',
controller: 'WizardMainController'
})
// nested states
// each of these sections will have their own view
// url will be nested (/form/profile)
.state('wizard.offer', {
url: '/offer',
templateUrl: 'OfferForm',
controller: 'OfferCtrlr'
})
// url will be /form/interests
.state('wizard.customizations', {
url: '/customizations',
templateUrl: 'OfferCustomizations',
controller: 'CustomizationCtrlr'
});
// catch all route
// send users to the form page
$urlRouterProvider.otherwise('/wizard/offer');
});
productCatalogApp.controller('WizardMainController', function ($scope) {
// we will store all of our form data in this object
$scope.formData = {};
// function to process the form
$scope.SaveForm = function () {
alert('awesome!');
$scope.formData = { "Offer": $scope.offer, QuestionGroups: $scope.QuestionGroups }
};
});
This is how i'm registering my controllers. Below is the one for offercontroller.
var app = angular.module('ProductCatalog.controllers', []);
app.controller('OfferCtrlr', function ($scope, $http, $modal) {
});
Any help will be appreciated.

Related

it just keep loading the same page with angular ngRoute?

I am learning angular by building a simple bookstore web app using nodejs as a restful api server. I built the server and it works fine, but once it comes to the front end I face an issue. I built the main page using angular ngRoute to get the data from the server and presented as following:
the picture and the title and the description angular read it with no problem but once I press the button "View Details" I should be redirected to a details page using the book id from the server.
From the front End the route provider:
var myApp = angular.module('myApp', ['ngRoute']);
myApp.config(function($routeProvider){
$routeProvider.when('/',{
controller: 'BooksController',
templateUrl: 'views/books.html'
})
.when('/books',{
controller: 'BooksController',
templateUrl: 'views/books.hrml'
})
.when('/books/details/:id',{
controller: 'BooksController',
templateUrl: 'views/book_details.html'
})
.when('/books/add', {
controller: 'BooksController',
templateUrl: 'views/add_book.html'
})
.when('/books/edit/:id', {
controller: 'BooksController',
templateUrl: 'views/edit_book.html'
})
.otherwise({
redirectTo: '/'
})
});
Books Controller:
var myApp = angular.module('myApp');
myApp.controller('BooksController', ['$scope', '$http', '$location',
'$routeParams', function($scope, $http, $location, $routeParams){
console.log('BooksController loaded...');
$scope.getBooks = function(){
$http.get('/api/books').then(function(response){
$scope.books = response.data;
});
}
$scope.getBook = function(){
var id = $routeParams.id;
$http.get('/api/books/'+id).then(function(response){
$scope.book = response.data;
});
}
}]);
books html where the panel being designed:
<div class="panel panel-default" ng-init="getBooks()">
<div class="panel-heading">
<h3 class="panel-title">Latest Books</h3>
</div>
<div class="panel-body">
<div class="row">
<div ng-repeat="book in books">
<div class="col-md-6">
<div class="col-md-6">
<h4>{{book.title}}</h4>
<p>{{book.description}}</p>
<a class="btn btn-primary"
href="#/books/details/{{book._id}}">View Details</a>
</div>
<div class="col-md-6">
<img class="thumbnail" src="{{book.image_url}}">
</div>
</div>
</div>
</div>
</div>
</div>
This the details book html where by clicking the button it must be redirected to:
details_book.html
<div class="panel panel-default" ng-init="getBook()">
<div class="panel-heading">
<h3 class="panel-title">{{book.title}}</h3>
</div>
<div class="panel-body">
<div class "row">
<div class ="col-md-4">
<img src="{{book.image_url}}">
</div>
<div class ="col-md-8">
<p>{{book.description}}</p>
<ul class="list-group">
<li class="list-group-item">Genre: {{book.genre}}</li>
<li class="list-group-item">Author: {{book.author}}</li>
<li class="list-group-item">Publisher: {{book.publisher}}
</li>
</ul>
</div>
</div>
</div>
</div>
and this is the get request from the server to prove the server working find using a certain id
The error I get once I open the main page:
And this error I get once I press the button:
Note: Once I press the button it give me this url:
http://localhost:3000/#!/#%2Fbooks%2Fdetails%2F599701c1f3da51117535b9ab
where the id is 599701c1f3da51117535b9ab which we can see it in the end of the url. But it should give url exactly such as:
http://localhost:3000/#!/books/details/599701c1f3da51117535b9ab
and once I write this url manually I get to the page which is the details with no problem but once I press the button from the book.html page I get the previews strange url again which is:
http://localhost:3000/#!/#%2Fbooks%2Fdetails%2F599701c1f3da51117535b9ab
Which load no where.
This is the github url for all the documents:
https://github.com/AbdallahRizk/BookStore.git
Any suggestions Please!!
use $rootScope instead of $scope for getBook function
$rootScope.getBook = function(){
var id = $routeParams.id;
$http.get('/api/books/'+id).then(function(response){
$scope.book = response.data;
});
init(getBook);
}
Note: add $rootScope to your BookController
Seems like I have hashprefix !, then my URL should also have ! after hash(#)
href="#!/books/details/{{book._id}}"
Since Angular 1.6 hashprefix is defaulted to !, you can disable this behavior by setting hashPrefix to ''(blank).
.config(['$locationProvider',
function($locationProvider) {
$locationProvider.hashPrefix('');
}
]);
Note: This answer from, #Pankaj Parkar at I get a weird templateURL not as it suppose to give with angular?

AnguarJS Routing Not Working As Expected

I have a listing of blog posts and I want to be able to click on the title and have it dynamically redirect to the proper posting.
So far it works except when I click on the anchor tagged title it redirects to:
blog/#/post/:post
rather than
blog#/post/:post
I've tried to change the href to data-ng-href,
using target="_self"
and tried changing the href="#/post/{{post}}" and href="/post/{{post}}"
Routes:
(function(){
'use strict';
angular.module('ghpg')
.config(Config);
Config.$inject = ['$routeProvider'];
function Config($routeProvider){
$routeProvider
.when('/listing', {
templateUrl: '/angular/views/listing.client.view.html'
}).otherwise({
redirectTo:'/'
}).when('/post/:title',{
templateUrl: '/angular/views/post.client.view.html',
controller: 'postController',
controllerAs: 'post'
}).otherwise({
redirectTo:'/listing'
});
}
})();
Listing View:
(function(){
'use strict';
angular
.module('ghpg')
.controller('listingController', listingController);
listingController.$inject = ['$scope', 'blogContent'];//,'blogContent'] //, 'blogContent'];
////
function listingController($scope, blogContent){
var vm = this;
vm.articles = [];
grabData();
function grabData(){
return blogContent.getContent().then(function(data){
console.log(data.articles);
vm.articles = data.articles;
return vm.articles;
},function(err){
console.log(err);
vm.data = [];
});
}
}
})();
App.js:
(function(){
'use strict';
var dependencies = [
'ghpg',
'ngRoute'
];
angular.module('blogger', dependencies)
.config(Config);
Config.$inject = ['$locationProvider']
function Config($locationProvider){
$locationProvider.hashPrefix('!');
}
if (window.location.hash === '#_=_'){
window.location.hash = '#!';
}
//bootstrap angular
angular.element(document).ready(function(){
angular.bootstrap(document, ['ghpg']);
});
})();
LISTING VIEW:
<div class="container-fluid" data-ng-Controller="listingController as vm">
<h2> Listings </h2>
<div class="row">
<div class="col-md-4"></div>
<div class="col-md-8">
<div class="post-listing" data-ng-repeat="post in vm.articles">
<h3 class="article-title"><a target="_self" data-ng-href="/blog#/post/{{post.title}}"> {{ post.title }} </a></h3>
<div class="article-container">
<div class="article-date"><span class="article-date">{{ post.date }}</span></div>
<div class="article-post>"><span class="article-content"> {{ post.content }} </span></div>
</div>
</div>
</div>
</div>
</div>
Having trouble where I went wrong. I strongly suspect that it's some small typo or something with my SPA location/locationProvider in app.js but it looks the same in my other apps, unless my eyes are fooling me (which could be totally happening!)
What I did for a fix was simply this:
changed the listing view's anchor:
<h3 class="article-title"><a target="_self" data-ng-href="/post/{{post.title}}"> {{ post.title }} </a></h3>
to include the /blog# portion in the href so that I have:
<h3 class="article-title"><a target="_self" data-ng-href="/blog#/post/{{post.title}}"> {{ post.title }} </a></h3>
Simple fix, cause only the blog portion or webpage of my website is the angularJS, everything else is not so the routing was not being called to route it until it saw /blog# as part of the app.

AngularJS: How to refresh parent controller

When the index.html page is rendered my ApplicationController will be called. When I login (login success)I want to refresh my ApplicationController. How to do it?
I have defined below Controllers in my application.
1)Login
angular.module('aclf').controller('LoginController', LoginController);
// The $inject property is an array of service names to inject.
LoginController.$inject = [ '$location', 'AuthenticationService',
'FlashService' ];
function LoginController($location, AuthenticationService, FlashService) {
var loginController = this;
loginController.login = login;
(function initController() {
// reset login status
AuthenticationService.ClearCredentials();
})();
function login() {
loginController.dataLoading = true;
AuthenticationService.Login(loginController.username,
loginController.password, function(response) {
if (response.username === loginController.username) {
console.log(response.authToken);
AuthenticationService.SetCurrentUser(
loginController.username,
response.authToken, true);
$location.path('/home');
} else {
FlashService.Error(response.message);
loginController.dataLoading = false;
}
});
}
;
}
2)ApplicationCotroller
angular.module('aclf').controller('ApplicationController',
function($scope,$rootScope) {
$scope.currentUser = $rootScope.globals.currentUser;
console.log('Inside ApplicationController');
})
3)HomeController- When home controller rendered I want to refresh the portion, since it contains currentUser.
/**
* Home Controller
*/
angular.module('aclf').controller('HomeController', HomeController);
// The $inject property is an array of service names to inject.
HomeController.$inject = [ 'UserService', '$rootScope' ];
function HomeController(UserService, $rootScope) {
var homeController = this;
homeController.user = null;
initController();
function initController() {
loadCurrentUser();
}
function loadCurrentUser() {
UserService.GetByUsername($rootScope.globals.currentUser.username)
.then(function(user) {
homeController.user = user;
});
}
}
4)This is my index.html page
Here I have defined my ApplicationController on body part. This needs to be refreshed at least after login and logout
<body data-ng-controller="ApplicationController">
<!-- TOPBAR START -->
<div id="layout-topbar" data-ng-show="currentUser">
<ul id="top-menu">
<li>
<span class="Fs22 FontRobotoLight">Welcome {{currentUser.username}} </span>
</li>
<li>
Logout
</li>
</ul>
</div>
<!-- TOPBAR END -->
<div id="wrapper">
<div id="wrapperIndent">
<div id="layout-menu-cover" class="Animated05 ps-container">
<div class="ps-scrollbar-x-rail" style="left: 0px; bottom: 3px;">
<div class="ps-scrollbar-x" style="left: 0px; width: 0px;"></div>
</div>
<div class="ps-scrollbar-y-rail" style="top: 0px; right: 3px;">
<div class="ps-scrollbar-y" style="top: 0px; height: 0px;"></div>
</div>
</div>
<div id="layout-portlets-cover">
<div class="Container96 Fnone MarAuto">
<div class="Container100">
<div class="ContainerIndent">
<div class="EmptyBox10"></div>
<div
data-ng-class="{ 'alert': flash, 'alert-success': flash.type === 'success', 'alert-danger': flash.type === 'error' }"
data-ng-if="flash" data-ng-bind="flash.message"></div>
<div data-ng-view></div>
</div>
</div>
<!-- footer -->
<div class="Container100">
<div class="ContainerIndent TexAlCenter Fs14">
Angular | All Rights Reserved.</div>
</div>
</div>
</div>
</div>
</div>
</body>
PS: I am very new to AngularJS
I have tried with reload page stuff. But it was not working.
I removed Application Controller and used
$routeProvider.when('/home', {
controller : 'HomeController',
templateUrl : 'partials/home.html',
controllerAs : 'homeController',
leftNav : 'partials/left-nav-main.html',
topNav: 'partials/top-nav.html'
})
.when('/login', {
controller : 'LoginController',
templateUrl : 'partials/login.html',
controllerAs : 'loginController'
})
Here the templateUrl property in the route definition references the view template that is loaded in the ng-view directive of the div element. I tried to simulate something similar to what Angular does for our left
and top navigation.
The value of the topNav property is used to load the top navigation view in the topnav div element ("id = top-nav") using the ng-include directive. We do the same for left navigation too. The ng-if directive in the left-nav section is used to hide left navigation if the current route configuration does not define the leftNav property.
The last part of this integration is setting up the currentRoute property and
binding it to ng-include. Angular sets up the ng-view template using the route configuration templateUrl property, but it does not know or care about the topNav and leftNav properties that we have added. We need to write some custom code that binds the navigation URLs with the respective ng-includes directives.
$scope.$on('$routeChangeSuccess', function (e, current, previous) {
$scope.currentRoute = current;
});
Here is my index.html
<div class="navbar navbar-default navbar-fixed-top top-navbar">
<!--Existing html-->
<div id="top-nav-container" class="second-top-nav">
<div id="top-nav" ng-include="currentRoute.topNav"></div>
</div>
</div>
<div class="container-fluid">
<div id="content-container" class="row">
<div class="col-sm-2 left-nav-bar"
ng-if="currentRoute.leftNav">
<div id="left-nav" ng-include="currentRoute.leftNav"></div>
</div>
<div class="col-sm-10 col-sm-offset-2">
<div id="page-content" ng-view></div>
</div>
</div>
</div>
Now the left-nav and top-nav appears only in home page and does not appear in login page.
Well, I think the best practice is to reload the entire page:
If you are using angular-ui/ui-router
$state.reload();
If you use another router
$route.reload();

Angular ng-bind disappearing using escaped fragments with Mean-SEO

I have an angular web app that I am trying to get escaped_fragments to work using Mean-seo (under the covers it uses phantomjs headless browser)
I am getting strange behaviour I can't explain.
The non escaped fragment works fine.
With escaped fragments some of the content immediately disappears.
I have an object that I am reading from the mongo db in the resolve section of the routes config like so.
state('view-creator-test', {
url: '/view-creator-test/:creatorId',
templateUrl: 'modules/creators/views/view-creator-test.client.view.html',
resolve: {
creator: function($stateParams, Creators) {
return Creators.get({
creatorId: $stateParams.creatorId
}).$promise;
}
},
controller: function($scope, creator) {
$scope.resolveCreator = creator;
}
}).
then the view template is
<section data-ng-controller="CreatorTestController" >
<!-- !CREATOR PROFILE -->
<section class="profile-header inverse">
<div class="container">
<!-- AVATAR -->
<div class="row">
<!-- NAME / LOCATION -->
<div class="col-sm-8 col-sm-offset-1 col-xs-12 text-center-sm">
<div class="row">
<div class="col-sm-6 col-xs-12">
<h2 class="name">{{creator.name}}</h2>
<h2 class="name" ng-bind="creator.name"></h2>
</div>
<h2 class="name">{{test}}</h2>
<h2 class="name" ng-bind="test"></h2>
</div>
</div>
</div>
</div>
</section>
</section>
then the controller is
'use strict';
angular.module('creators').controller('CreatorTestController', ['$scope',
function($scope) {
$scope.test = 'Leo was Here';
$scope.creator = $scope.resolveCreator;
}]);
the result is that the creator name is filled in for {{creator.name}} but is not filled in for ng-bind="creator.name".
'Leo was here' is filled in for both.
Thanks
Instead of defining controller function in state and then do assign that $scope inside variable through template, you could place the CreatorTestController inside the route, so that you directly inject the dependency inside the CreatorTestController function, Remove ng-controller from the template
.state('view-creator-test', {
url: '/view-creator-test/:creatorId',
templateUrl: 'modules/creators/views/view-creator-test.client.view.html',
resolve: {
creator: function($stateParams, Creators) {
return Creators.get({
creatorId: $stateParams.creatorId
}).$promise;
}
},
controller: 'CreatorTestController'
})
Controller
'use strict';
angular.module('creators').controller('CreatorTestController', ['$scope', 'creator', //<-- injected resolve method here.
function($scope, creator) {
$scope.test = 'Leo was Here';
$scope.creator = creator;
}]);

Could not resolve '___' from state 'home' - angular ui-router issue

I'm new to angular and following this tutorial:
https://scotch.io/tutorials/angularjs-multi-step-form-using-ui-router
but i'm injecting this module into another existing module.
However, I keep getting a "could not resolve states" error - I'm not sure why but suspect its either a routes issue and I'm being dumb, or otherwise its a nested views issue (note nesting of ui-view in index.html, and again in home.html).
using angular ui version 0.2.13
angular version 1.3.14
Please help!!
Below is the relevant code:
structure:
home.html
<div id="form-container">
<div class="page-header text-center">
<h2>Let's Be Friends</h2>
<!-- the links to our nested states using relative paths -->
<!-- add the active class if the state matches our ui-sref -->
<div id="status-buttons" class="text-center">
<a ui-sref-active="active" ui-sref=".profile"><span>1</span> Profile</a>
<a ui-sref-active="active" ui-sref=".interests"><span>2</span> Interests</a>
<a ui-sref-active="active" ui-sref=".payment"><span>3</span> Payment</a>
</div>
</div>
<!-- use ng-submit to catch the form submission and use our Angular function -->
<form id="signup-form" ng-submit="processForm()">
<!-- our nested state views will be injected here -->
<div id="form-views" ui-view></div>
</form>
</div>
<!-- show our formData as it is being typed -->
<pre>
{{ formData }}
</pre>
index.html
<body> blah blah
<div ui-view></div>
<script src="app.js"></script>
<script src="javascripts/form.js"></script>
<script src="controllers/main.js"></script>
<script src="controllers/form-controller.js"></script>
</body
app.js
angular.module('MyApp', ['ngCookies','ngResource', 'ngMessages', 'mgcrea.ngStrap', 'formApp'])
.config(['$locationProvider', '$stateProvider', function($locationProvider, $stateProvider){
$locationProvider.html5Mode(true);
console.log($stateProvider);
}]);
form.js
angular.module('formApp', ['ngAnimate', 'ui.router'])
// configuring our routes
// =============================================================================
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
// route to show our basic form (/form)
.state('home', {
url: '/',
templateUrl: 'views/home.html',
controller: 'formController'
})
// nested states
// each of these sections will have their own view
// url will be nested (/form/profile)
.state('.profile', {
url: '/profile',
templateUrl: 'views/form-profile.html'
})
// url will be /form/interests
.state('.interests', {
url: '/interests',
templateUrl: 'views/form-interests.html'
})
// url will be /form/payment
.state('.payment', {
url: '/payment',
templateUrl: 'views/form-payment.html'
});
// catch all route
// send users to the form page
$urlRouterProvider.otherwise('/');
})
form-controller.js
// our controller for the form
// =============================================================================
angular.module('formApp')
.controller('formController', ['$scope', function($scope) {
// we will store all of our form data in this object
$scope.formData = {};
// function to process the form
$scope.processForm = function() {
alert('awesome!');
};
}]);
Your code is not following the tutorial exactly. Note that for child states to function, they must reference their parent state.
In the tutorial code:
.state('form.profile', {
In your code:
.state('.profile', {
If you change your child states to reference the parent, they will function correctly. i.e.
.state('home.profile', {

Resources