Angularjs $urlRouterProvider.otherwise not working with MVC5 until page refresh - angularjs

I am working on a mvc5 application (not spa) but in one of my pages, I am creating a multi step form and chose angular. Everything is working if I refresh the page, but when I click on the link that redirects me to my page with angular, the ui-router is not working.
index.chtml
<div class="row" ng-app="formApp">
<!-- views will be injected here -->
<div ui-view></div>
</div>
<script>
require(["angular", "ngAnimate", "ui.router"], function (angular, ngAnimate, router) {
angular.module('formApp', ['ngAnimate', 'ui.router'])
// configuring our routes
// =============================================================================
.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
// route to show our basic form (/form)
.state('form', {
url: '/form',
templateUrl: "/AutoAccident/Form",
controller: 'formController'
})
// nested states
// each of these sections will have their own view
// url will be nested (/form/profile)
.state('form.profile', {
url: '/profile',
templateUrl: "/AutoAccident/FormProfile",
})
// url will be /form/interests
.state('form.interests', {
url: '/interests',
templateUrl: "/AutoAccident/FormInterests",
})
// url will be /form/payment
.state('form.payment', {
url: '/payment',
templateUrl: "/AutoAccident/FormPayment",
});
// catch all route
// send users to the form page
$urlRouterProvider.otherwise('/form/profile');
})
// our controller for the form
// =============================================================================
.controller('formController', 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!');
};
});
});
</script>
My issue is that when i go to //mydevurl/AutoAccident/Index which triggers the code above, I am getting
Uncaught Error: [$injector:modulerr]
https://docs.angularjs.org/error/$injector/modulerr?p0=formApp&p1=Error:%20%5B$injector:nomod%5D%20http:%2F%2Ferrors.angularjs.org%2F1.4.5%2F$injector%2Fnomod%3Fp0%3DformApp%0A%20%20%20%20at%20Error%20(native)%0A%20%20%20%20at%20http:%2F%2Flocalhost:51416%2FScripts%2Flibs%2Fangular%2Fangular.min.js:6:416%0A%20%20%20%20at%20http:%2F%2Flocalhost:51416%2FScripts%2Flibs%2Fangular%2Fangular.min.js:24:78%0A%20%20%20%20at%20a%20(http:%2F%2Flocalhost:51416%2FScripts%2Flibs%2Fangular%2Fangular.min.js:23:141)%0A%20%20%20%20at%20http:%2F%2Flocalhost:51416%2FScripts%2Flibs%2Fangular%2Fangular.min.js:23:384%0A%20%20%20%20at%20http:%2F%2Flocalhost:51416%2FScripts%2Flibs%2Fangular%2Fangular.min.js:37:332%0A%20%20%20%20at%20n%20(http:%2F%2Flocalhost:51416%2FScripts%2Flibs%2Fangular%2Fangular.min.js:7:322)%0A%20%20%20%20at%20g%20(http:%2F%2Flocalhost:51416%2FScripts%2Flibs%2Fangular%2Fangular.min.js:37:180)%0A%20%20%20%20at%20eb%20(http:%2F%2Flocalhost:51416%2FScripts%2Flibs%2Fangular%2Fangular.min.js:40:435)%0A%20%20%20%20at%20d%20(http:%2F%2Flocalhost:51416%2FScripts%2Flibs%2Fangular%2Fangular.min.js:19:381,
but when I try to refresh by clicking refresh button of my browser, the app works and my URI becomes http://mydevurl/AutoAccident/Index#/form/profile automatically and shows my multi step form.
Same error when I click my menu. My multistep form is not the default page when my app loads.
<li>Auto Accident</li>

Related

Angularjs - Clueless on how to redirect to Home page from Login page which has a different view

I am working on a AngularJs project where I have a Login page and Home page (all other pages will use the same home page view). Now I need to redirect the user from Login page (different layout) to Home page (another different layout).
Right now I have a Index page which contains both ng-app & ng-view tags and my Login page is getting rendered on that but after successful login I don't know how to show my different layout view (Home page).
Also, I have seen many people saying that you can use ng-if to hide/show the required piece (which is placed in same page itself). So, I tried using the rootScope variable to show/hide the span/div before and after login & I worked well. But one thing I noticed in this method is, when I load the login page I was able to see the sidebar, topbar & bottompanel for few seconds but they eventually become invisible and it looks messy.
My app.js:
$stateProvider
.state('login', {
url: "/login",
templateUrl: "/app/views/login/login.html",
controller: "loginController"
})
.state('home', {
url: "/home",
templateUrl: "/app/views/home/home.html",
controller: "homeController"
})
My login page: Very simple page - Contains just two textboxes and a button. When clicking the Login button loginController's login method will be called.
My home page: Very complex page - Contains a side panel, top panel, center panel (where all other views will be displayed) and bottom panel.
I have tried ng-if in the index page to show/hide login and home page using a rootScope variable (called isLoginSuccessful)
My Index page:
<html data-ng-app="myApp">
<body>
<div class="sidebar" id="sidebar" ng-if="isLoginSuccessful">
</div>
<div class="topbar" id="topbar" ng-if="isLoginSuccessful">
</div>
<div class="contentpanel" id="contentpanel">
<div ng-view>
<!-- view goes here-->
</div>
</div>
<div class="bottompanel" id="bottompanel" ng-if="isLoginSuccessful">
</div>
</body>
</html>
My loginController.js:
myApp.controller('loginController', ["$scope", "$rootScope", "$location", function ($scope, $rootScope, $location) {
$rootScope.loggedIn = false;
$scope.login = function () {
//do user validation check here
$rootScope.loggedIn = true;
$location.path("/home"); //redirect to home page
}
}]);
Is there any better way to handle this. Please help me.
Thanks in advance.
You asked how you navigate from the login page to the home page once you have logged in? Your logic is nearly there in the controller, and you have the states already set up, so alter it like so:
myApp.controller('loginController', ["$scope", "$rootScope", "$state", function ($scope, $rootScope, $state) {
$rootScope.loggedIn = false;
$scope.login = function () {
//do user validation check here
$rootScope.loggedIn = true;
$state.go('home'); //redirect to home page
}
}]);
Since the templates contain everything you need, you can get rid of the ng-if attributes since the only way they can navigate to the home page is via the login (and via the $state.go())
The best approach is to use Angular UI router. Take a look here https://angular-ui.github.io/ui-router/
EDIT:
It should work:
app.js
$stateProvider
.state('login', {
url: "/login",
views: {
"content#": {
templateUrl: "/app/views/login/login.html",
controller: "loginController"
}
}
})
.state('home', {
url: "/home",
views: {
"sidebar#": {
templateUrl: "/app/views/home/sidebar.html",
controller: "sidebarController"
},
"topbar#": {
templateUrl: "/app/views/home/topbar.html",
controller: "topbarController"
},
"content#": {
templateUrl: "/app/views/home/home.html",
controller: "homeController"
}
"bottompanel#": {
templateUrl: "/app/views/home/bottompanel.html",
controller: "bottompanelController"
}
}
})
index.html
<html data-ng-app="myApp">
<body>
<div class="contentpanel" id="contentpanel">
<div ui-view="sidebar"></div>
<div ui-view="topbar"></div>
<div ui-view="content"></div>
<div ui-view="bottompanel"></div>
</div>
</body>
</html>
loginController.js
myApp.controller('loginController', ["$scope", "$rootScope", "$state",
function ($scope, $rootScope, $state) {
$rootScope.loggedIn = false;
$scope.login = function () {
//do user validation check here
$rootScope.loggedIn = true;
$state.go("home"); //redirect to home page
}
}]);

AngularJS: How to prevent the angular controller to be loaded every time partial page routed

I have three partial pages in my application and I am using ng-View directive to route to the pages. Also I have separate controller for pages. Now in two of the pages I am making http calls to get / post data, where I am using service to call REST APIs.
Now the problem I am facing every time I am routed to a page, it gets loaded again (executing the function which is making http calls).
In a post like this I saw it is said that this is a default behavior but if so, how can I prevent this to happen. The link I saw is:
The link
Now how can I prevent that to happen, I really do not need to load pages after it is loaded for the first time, when routed.
The code snippets are as follows..
In index.html
To call page link:
...
<md-button class="md-primary" ng-href="#/">Report</md-button>
<md-button class="md-primary" ng-href="#about">About</md-button>
...
<div ng-view></div>
....
In partial1.html, I am not assigning any controller.
In App.js file, setting the route config...
angular
.module('webApp')
.config(function ($routeProvider) {
$routeProvider
.when('/', {
//url: "/report",
templateUrl: 'pages/report.html',
controller: 'ReportController'
})
.when('/about', {
templateUrl: 'pages/about.html',
controller: 'aboutController'
})
.....
In controller ....
angular
.module('webApp')
.controller('ReportController',
function ($scope, $log, $mdDialog, webAppService) {
var GetReportsFromDB = function () {
webAppService.GetReports().success(function (rptData) {
var dd = JSON.parse(rptData);
rptvm.reports = dd;
}).error(function (response) {
console.log(response);
}).then(function () {
});
};
GetReportsFromDB();
...
In Service ...
angular
.module('webApp')
.service('webAppService', ['$http', function ($http) {
var svc = {};
svc.GetReports = function () {
console.log('loading...');
return $http({
method: 'GET',
url: 'http://somedomain/api/mycontroller/myaction',
});
};
......
I am very new at AngularJS. Any help will be appreciated.
Thanks in advance,
Arpan

url change not triggering state change with angular ui router

I'm using angular ui router to create a home route like this
routes.$inject = ['$stateProvider'];
export default function routes($stateProvider) {
$stateProvider
.state('home', {
url: '/',
template: require('./home.html'),
controller: 'HomeController',
controllerAs: 'home'
})
In the HomeController, I'm importing a service that provides a stream of blog posts. Thus, in the ./home.html template, I am iterating through the array of posts like this, creating links for each post
<span ng-repeat="post in home.posts">
<a ui-sref="home.detail({postId:post.id})">{{post.title.rendered}}</a>
</span>
As you can see from the link, I'm expecting a click of the link to be handled by home.detail state. In the router, I do this, expecting each post to have a url (when I click the links) something like http://localhost:8888/1 or http://localhost:8888/4. However, when I click the links, the url changes but the ./post.html template doesn't load and the log statement in the controller code below doesn't run. There are no errors in the console.
Question: why is the router code to handle the click of the individual links (to load the new template, to log the stateParams) not running when I click the links to the posts (yet the url changes)?
$stateProvider
.state('home', {
url: '/',
template: require('./home.html'),
controller: 'HomeController',
controllerAs: 'home'
})
.state('home.detail', {
url: '{postId:[0-9]{1,4}}',
template: require('./post.html'),
controller: ['$scope', '$stateParams',
function ( $scope, $stateParams) {
console.log($scope, "$scope", $stateParams, "$stateParams");
$scope.post = $stateParams;
}],
Your parent state needs a ui-view. From ui-router's documentation
Child states will load their templates into their parent's ui-view.

What to use exactly to navigate data between views/controllers in ionic

I've started developing a simple application :
in the first view I'm retreiving all the games, and the other view i'm retreivig the game details according to the game id.
I didn't link the two pages yet.
this is what i'm facing as problem. i'm confused ! should I use ion-view ?? or I should use a normal page
for each view I have a controller which look almost like :
.controller('tomorrowmatches', function($scope, $http) {
$http.get("http://www.myappbackend/ofc/matches?date=2015-05-03")
.success(function (response) {
$scope.matches = response;
}
});
})
and how to pass data from conroller to another, in my example I wanna pass the game.id as shwon on the screenshot.
if you need more details just let me know. I just need someone to make things clear for me, and if there is an example it would be fantastic.
To pass data to another view you can use the $state and $stateParams services.
Example
Controller 1 (sends the data)
.controller('MyCtrl1', function($scope, $state) {
$scope.selectedData = function(selectedId) {
$state.go('yourState', { id: selectedId });
};
})
Controller 2 (gets the data)
.controller('YourCtrl', function($scope, $state, $stateParams) {
if ($stateParams.id) {
$scope.yourParam = $stateParams.id;
}
// Do anything you want with the ID inside $scope.yourParam
})
app.js
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('init', {
url: "/init",
templateUrl: "templates/init.html",
controller: "MyCtrl1"
})
.state('yourState', {
url: "/yourState?id",
templateUrl: "templates/your-template.html",
controller: "YourCtrl"
})
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/init');
})
As you can see in the state yourState I assigned an id as a parameter. This parameter will be checked if exists by YourCtrl, if it exists assign to scope and then do whatever you want with it.
Remember to set the parameter options in your app.js route configuration.
Check the ui-router docs for more info on this. You have more ways to send data.
First of all you need the ion view as a container for your views/templates..
<body ng-app="myapp">
<ion-nav-view></ion-nav-view>
</body>
then on your app.js you need to configure your routing..
// Ionic Starter App
angular.module('myapp', ['ionic', 'myapp.controllers', 'myapp.services', 'myapp.directives'])
.run(function($ionicPlatform) {
$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);
}
if (window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
})
.config(function($stateProvider, $urlRouterProvider, $httpProvider) {
// Ionic uses AngularUI Router which uses the concept of states
// Learn more here: https://github.com/angular-ui/ui-router
// Set up the various states which the app can be in.
// Each state's controller can be found in controllers.js
// $httpProvider.defaults.useXDomain = true;
$stateProvider
//Page1
.state('page1', {
url: "/page1",
templateUrl: "templates/page1.html",
controller: "Page1Controller"
})
//Page2
.state('page2', {
url: "/page2",
templateUrl: "templates/page2.html",
controller: "Page2Controller",
})
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/page1');
});
Note: Make sure that all dependencies for ionic are included on your folder and called on your index.html..
Hope this helps :)

Failed to load parent route in angular UI-Router

In my app I have some main modules and each modules has sidebar.
If I click sidebar item then it will route to sidebar linking page but here if I click header again then I am not able to view my parent route page.
I have listed my problem in this plnkr.
Step to reproduce :
By default route1 is selected and dashboard is available on view. Click on Item1.
Now click on route1 : Failed to see dashboard view.
<script>
var myapp = angular.module('myapp', ["ui.router"])
myapp.config(function($stateProvider, $urlRouterProvider) {
// For any unmatched url, send to /route1
$urlRouterProvider.otherwise("/route1")
$stateProvider
.state('route1', {
url: "/route1",
templateUrl: "route1.html",
controller: function($scope, $state) {
$scope.items = ["item1", "item2"];
$state.go('route1.dashboard');
}
})
.state('route1.dashboard', {
url: "/dashboard",
templateUrl: "dashboard.html"
})
.state('route1.item1', {
url: "/item1",
templateUrl: "item1.html"
})
.state('route1.item2', {
url: "/item2",
templateUrl: "item2.html"
})
.state('route2', {
url: "/route2",
templateUrl: "route1.html",
controller: function($scope, $state) {
$scope.items = ["item3", "item4"];
$state.go('route2.dashboard');
}
})
.state('route2.dashboard', {
url: "/dashboard",
templateUrl: "dashboard.html"
})
.state('route2.item3', {
url: "/item3",
templateUrl: "item3.html"
})
.state('route2.item4', {
url: "/item4",
templateUrl: "item4.html"
})
})
</script>
The code you have in the route1 controller only runs when it's instantiated. Therefore, after you re-visit it from being inside item1, it doesn't need to reload and the $state.go() doesn't fire.
I've forked your plunker with another potential approach: http://plnkr.co/edit/7stMErnkb3rzPJD0Gj5x?p=preview
you should put the dashboard content in the route1 template, rather than attempting to forward to it via $state.go()
so, your route1.html goes from the previous ui-view statement of
<div ui-view></div>
to
<div ui-view>
<h1>Dashboard</h1>
</div>
Now you don't need the dashboard partial, and it loads every time. The item1/item2 partials will replace the content in the ui-view whenever those states activate.
Note in the updated Plunker how Route1 works as you want, while Route2 still doesn't work (as it still has the previous $state.go() approach).

Resources