ocLazyLoad + UI Router navigating back to child view after page refresh - angularjs

I'm using ocLazyLoad with AngularJS and AngularJS UI Router to load AngualarJS modules on demand. I have a Posts view/state and Post view/state in different modules and I can simply navigate between them.
The only issue is that when I'm on /posts/1 and manually refresh the page, it goes back to /. I understand that it makes perfect sense because app.js is the only file that gets loaded after page refresh but what I don't understand is how to make it lazy load the same /posts/1 view again after refreshing the page. I tried using $urlRouterProvider.when in app.js but had no luck.
I have created a plunker for this: http://plnkr.co/edit/lPb2qCGF9KLL16jVoLQo?p=info
app.js
angular.module('app', ['ui.router', 'oc.lazyLoad'])
.run(['$rootScope', '$state', '$stateParams',
function ($rootScope, $state, $stateParams) {
$rootScope.state = $state;
$rootScope.stateParams = $stateParams;
}
])
.config([
'$ocLazyLoadProvider',
'$stateProvider',
'$urlRouterProvider',
function ($ocLazyLoadProvider, $stateProvider, $urlRouterProvider) {
// For any unmatched url, redirect to /
$urlRouterProvider.otherwise('/');
$stateProvider
.state('app', {
url: '/',
views: {
header: {
template:
'<nav class="navbar navbar-default">' +
'<div class="container-fluid">' +
'<ul class="nav navbar-nav">' +
'<li><a ui-sref="app">Home</a></li>' +
'<li><a ui-sref="app.posts">Posts</a></li>' +
'</ul>' +
'</div>' +
'</nav>'
},
content: {
template: '<h3>Home view</h3>'
}
}
})
.state('app.posts', {
url: 'posts',
views: {
'content#': {
templateUrl: 'posts.html',
controller: 'PostsController',
resolve: {
load: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load({
serie: true,
files: [
'posts.js',
'posts-controller.js'
]
});
}]
}
}
}
});
}
]);
posts.js
angular.module('app.posts', ['ui.router', 'oc.lazyLoad'])
.config([
'$ocLazyLoadProvider',
'$stateProvider',
function ($ocLazyLoadProvider, $stateProvider) {
$stateProvider
.state('app.posts.post', {
url: '/:id',
views: {
post: {
templateUrl: 'post.html',
controller: 'PostController',
resolve: {
post: ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load({
serie: true,
files: [
'post.js',
'post-controller.js'
]
});
}]
}
}
}
});
}
]);
post.js
angular.module('app.posts.post', []);

Lazy Loading ui-router states with ocLazyLoad and ui-router-extras futureStates
http://bardo.io/2014/08/26/oclazyload-future-states/

Related

cannot resolve from state ' ' . What configuration did i put wrong?

I am trying to go using ui-sref but it's saying cannot resolve from ''. What did I do wrong in the route configuration. Everything seems correctly configured from my point of view. But i am getting this error.
view
<li><a ui-sref="container.demurrage.index">Container Management</a></li>
Js
angular.module("app.container",
[
"ui.router",
"ui.select",
"ui.bootstrap",
])
.config([
"$stateProvider", function ($stateProvider) {
$stateProvider.state("container",
{
url: "/container",
template: "<div ui-view></div>",
abstract: true
});
$stateProvider.state("container.demurrage.index",
{
url: "/demurrage",
templateUrl: "/container/demurrageindex",
controller: "demurrageIndexController",
resolve: {
}
});
}
])
For someone who has the same issue, I post the solution and it was the naming issue.
If the parent is container the children should be container.{some name} NOT container.{name}.{name}.
angular.module("app.container",
[
"ui.router",
"ui.select",
"ui.bootstrap",
])
.config([
"$stateProvider", function ($stateProvider) {
$stateProvider.state("container",
{
url: "/container",
template: "<div ui-view></div>",
abstract: true
});
$stateProvider.state("container.demurrageindex",
{
url: "/demurrage",
templateUrl: "/container/demurrageindex",
controller: "demurrageIndexController",
resolve: {
}
});
}
])

ui-router loggin page without menu

I'm a begginer with angular 1.6 and I would like to do the next:
Loggin, register & remember password without menu.
After loggin: Menu, nav bar and footer appears.
Up to now I have the next:
Index.html
<ui-view></ui-view>
Loggin: Works fine.
authenticationService.Login(vm.email, vm.password, function (result) {
if (result === true) {
$location.path('/main');
} else {
vm.error = 'Username or password is incorrect.';
vm.loading = false;
}
});
};
If I have logged I go to main, here my problems appear..
<!-- Wrapper-->
<div id="wrapper">
<!-- Navigation -->
<div ng-include="'../views/partials/main-navigation.html'"></div>
<!-- Page wraper -->
<div id="page-wrapper">
<!-- Topnavbar -->
<div ng-include="'../views/partials/main-topnavbar.html'"></div>
hola mundo
<!-- Main view -->
<div ui-view>aqui tengo que meter todas las vistas</div>
<!-- Footer -->
<div ng-include="'../views/partials/main-footer.html'"></div>
</div>
<!-- End page wrapper-->
Now I would like to put the rest of my web pages inside the main
<div ui-view>All pages here</div>
How Can I do this?
I have read several pages https://ui-router.github.io/ and some more, but It is not clear for me.
I think I have to do some in my app.js but I don't now what...
(function () {
'use strict';
angular.module('frontEndApp', [
'ui.router',
'ngMessages',
'ngStorage',
'ngAnimate',
'ngAria',
'ngCookies',
'ngMessages',
'ngResource',
'ngRoute',
'ngSanitize',
'ngTouch',
'ngStorage',
'ngResource',
'pascalprecht.translate']).config(config).run(run);
function config ($stateProvider, $translateProvider, $urlRouterProvider) { // default route
$urlRouterProvider.otherwise('/login');// app routes
var states = [
{ name: 'main', url: '/main', templateUrl: 'views/main/main.html' },
{ name: 'login', url: '/login', templateUrl: 'views/login/login.html', controller: 'loginController', controllerAs: 'vm' },
{ name: 'department', url: '/department', templateUrl: 'views/department/department.html', controller: 'departmentController', controllerAs: 'vm' }
];
// Loop over the state definitions and register them
states.forEach(function (state) {
$stateProvider.state(state);
});
/**
* Translation of the web page with angular-Translate
*/
$translateProvider.useStaticFilesLoader({
files: [{
prefix: '../config/languages/locale-',
suffix: '.json'
}]
});
$translateProvider.preferredLanguage('en');
$translateProvider.useSanitizeValueStrategy('escapeParameters');
}
function run ($rootScope, $http, $location, $localStorage) { // keep user logged in after page refresh
if ($localStorage.currentUser) {
$http.defaults.headers.common.Authorization = 'Bearer ' + $localStorage.currentUser.token;
}
// redirect to login page if not logged in and trying to access a restricted page
$rootScope.$on('$locationChangeStart', function (event, next, current) {
var publicPages = ['/login'];
var restrictedPage = publicPages.indexOf($location.path()) === -1;
if (restrictedPage && !$localStorage.currentUser) {
$location.path('/login');
}
});
}
})();
Thanks in advance for your help.
Simply:
{ name: 'main', url: '/main', templateUrl: 'views/main/main.html' },
{ name: 'login', url: '/login', templateUrl: 'views/login/login.html',
controller: 'loginController', controllerAs: 'vm' },
{ name: 'main.department', url: '/department', templateUrl:
'views/department/department.html', controller: 'departmentController',
controllerAs: 'vm' }
If department belongs to main then call it: 'main.department'

Lazy loading modules

Whenever I attempt to go to profile state I'm thrown back to the home state (no errors in console).
Here's my setup:
app.js
angular.module('app',[
'oclazyLoad'
'app.components'
])
.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', '$httpProvider',
function ($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider) {
$urlRouterProvider.otherwise('/');
//$locationProvider.html5Mode(true);
$httpProvider.interceptors.push('jwtInterceptor');
function lazyLoad(pathjs) {
return ['$ocLazyLoad', function ($ocLazyLoad) {
return $ocLazyLoad.load(pathjs);
}];
}
$stateProvider
.state('home', {
url: '/',
template: 'asd'
})
.state('profile', {
url: '/profile',
templateUrl: 'components/profile/profile.html',
controller: 'profileCtrl',
controllerAs: 'vm',
resolve: {
module: lazyLoad('components/profile/profile.js'),
user: ['SessionService', function (SessionService) {
return {fake: 'user'};//SessionService.currentUser(true);
}]
}
})
}]);
angualar.module('app.components',[]);
profile.js
angular.module('app.components')
.controller('profileCtrl', ['user', function(user){
var vm = this;
vm.test = 123;
}]);
profile.html
<div>{{vm.test || 1}}</div>
This was an embarrasing problem but I forgot to return the response in my $http interceptor jwtInterceptor.

AngularJS: Nested named views from different modules

I'm using angular-ui-router to load nested named views.
In the index.html file I have an unnamed view and a named one.
Index.html:
<div ui-view="header"></div>
<div ui-view=""></div>
I load header.html to named view header. The header view has two named views contactsSearch and countries.
Header.html:
<div ui-view="contactsSearch"></div>
<div ui-view="countries"></div>
In the unnamed view of the index.html file I want to load contacts.html.
Contacts.html:
Contacts List
I use three modules: myApp, countries and contacts. I've configured the routes for each module.
MyApp module:
angular.module('myApp', ['ui.state', 'contacts', 'countries'])
.config(['$stateProvider', '$routeProvider',
function ($stateProvider, $routeProvider) {
$stateProvider
.state("home",
{
url: "/home",
abstract: true,
views: {
'header': {
template: "<div class ='row' ui-view ='countriesList'></div><div class ='row' ui-view ='contactsSearch'></div>"
},
"": {
template: "<div ui-view></div>"
}
}
});
}]);
Countries module:
angular.module('countries', ['ui.state'])
.config(['$stateProvider', '$routeProvider',
function ($stateProvider, $routeProvider) {
$stateProvider
.state("home.countries", {
url: "/countries",
views: {
'countriesList': {
template: "<p>Countries</p>"
}
}
});
}])
.run(['$rootScope', '$state', '$stateParams', function ($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
$state.transitionTo('home.countries');
}]);
Contacts module:
angular.module('contacts', ['ui.state'])
.config(['$stateProvider', '$routeProvider',
function ($stateProvider, $routeProvider) {
$stateProvider
.state("home.contacts", {//should be loaded to the unnamed view in index.html
url: "",
views: {
'contactsList': {
template: "<p>Contacts List</p>"
}
}
})
.state("home.contactsSearch", {
url: "/contactsSearch",
views: {
'contactsSearch': {
template: "<p>Contacts Search</p>"
}
}
});
}])
.run(['$rootScope', '$state', '$stateParams', function ($rootScope, $state, $stateParams) {
$rootScope.$state = $state;
$rootScope.$stateParams = $stateParams;
$state.transitionTo('home.contactsSearch');
}]);
My code is not correct because nothing is being displayed and I cannot figure out why. After some investigation, I've found out that a parent can have only one state, but I need home.contacts, home.contactsSearch and home.countries to have the same parent: home.
Can someone please help me with this?
I've created a jsfiddle for more details: https://jsfiddle.net/cjtnmbjw/3/
Thank you

how to reference a controller inside a sub-module in angularjs

I'm using modules /sub modules on the angular app, my controller doesn't load on a specific route but the view does, according to a comment on this question I should reference the child module inside the main module and that should do the trick.
this is my code for bootstrapping the app:
angular.module('mainApp', ['ui.bootstrap', 'ui.utils', 'ui.router', 'ngResource', 'ngAnimate', 'ngCookies', 'facebook', 'subModule1', 'subModule2', 'subModule3']);
angular.module('mainApp').config(function ($stateProvider, $urlRouterProvider, $locationProvider, FacebookProvider) {
$stateProvider.state("root",
{
url: '',
abstract: true,
views: {
'footer#': {
templateUrl: "/partial/footer/footer.html",
},
'header#': {
templateUrl: "/partial/header/header.html",
}
}
}).state('root.home', {
url: '/index',
views: {
'container#': {
templateUrl: '/partial/index/index.html',
controller: 'IndexCtrl'
}
},
}
).state('root.login', {
url: "/login",
views: {
'container#': {
templateUrl: '/partial/login/login.html',
controller: 'LoginCtrl'
}
},
});
FacebookProvider.init('xxxxxx');
$urlRouterProvider.otherwise('/index');
$locationProvider.hashPrefix('!');
});
I have the sub-module configuration in a separate folder named /subModule1/submodule1.js
angular.module('subModule1').config(function($stateProvider) {
$stateProvider.state("submodule1",
{
url: '',
abstract: true,
views: {
'footer#': {
templateUrl: "/partial/footer/footer.html",
},
'header#': {
templateUrl: "/partial/header/header.html",
}
}
}).state('submodule1.dashboard',
{
url: '/dashboard',
views: {
'container#': {
templateUrl: '/subModule1/partial/dashboard/dashboard.html',
controller: 'DashboardCtrl',
resolve: {
dashboardinfo: function($resource) {
var resourceGet = $resource('/submodule1/dashboard');
return resourceGet.get().$promise;
}
}
},
'sideBar#': {
templateUrl: '/submodule1/partial/sidebar/sidebar.html'
},
'navBar#': {
templateUrl: '/submodule1/partial/navbar/navbar.html'
}
}
});
});
the controller is defined as:
angular.module('subModule1').controller('DashboardCtrl', function ($scope, $interval, $resource, notification, dashboardinfo) { ... }
the index located on the root of the page which is the page layout have the
<html ng-app="mainApp">
and the controller have the ng-controller definiton as follows:
<div ng-controller="DashboardCtrl">
Everything is fine just the controller isn't running, it doesn't get executed by the view.
The ui-router and ng-controller="DashboardCtrl" are intended to work together. In the ui-router world we are assigning Controllers to views directly in the state definition.
So this (exactly as you have already have it, no change) is enough:
.state('submodule1.dashboard',
{
url: '/dashboard',
views: {
'container#': {
templateUrl: '/subModule1/partial/dashboard/dashboard.html',
controller: 'DashboardCtrl',
to say, that the view rendered inside of the ui-view="container" on the root (index.html) should be provided with DashboardCtrl.
There is an example using the above state definition (1:1 as possible).
This is the index.html content:
<div ui-view="header"></div>
<div ui-view="navBar"></div>
<div ui-view="container"></div>
<div ui-view="sideBar"></div>
<div ui-view="footer"></div>
And this links will correctly trigger the above states:
// root
<li><a ui-sref="root.home">root.home</a></li>
<li><a ui-sref="root.login">root.login</a></li>
// dashboard
<li><a ui-sref="submodule1.dashboard">submodule1.dashboard</a></li>
All the other details check here

Resources