I'm struggling a bit with having submodules in an Angular 1.3.9 app. I've got a (non-working, sorry) preview at http://plnkr.co/edit/XBfTPAGRRe0CWJgjGJzc?p=preview and I think it's freaking out, in part, because I'm using Restangular.
I have the following:
angular
.module('estimate', ['ui.router', 'restangular', 'estimate.project'])
;
angular
.module('estimate.project', ['ui.router'])
.config(['$stateProvider', '$urlRouterProvider', '$locationProvider'
, function($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state('project', {
url: "/project/{id:int}",
abstract: true,
templateUrl: '/app/templates/project.html',
controller: "ProjectController as project",
resolve: { // stuff }
})
.state('project.overview', {
url: "",
templateUrl: "/app/templates/overview.html"
})
// ...
;
}])
.controller('ProjectController', ['$scope', 'ProjectService', 'myProject'
, function($scope, ProjectService, myProject) {
console.log('i made it!');
}]);
And in my template, which is served from the estimate module, I have:
<li><a ui-sref="project.overview({ id: 1 })">One</a></li>
The URL resolves correctly on the page, but clicking on it does nothing. It doesn't even throw any console errors - it just sits there. My gut tells me it has to do with how I'm referring to the controllers and/or the routes, and if they need to be prefixed or modified to work with a submodule. Any ideas on how to get it to load properly?
If this post is too scatterbrained, let me know and I'll try to clean it up.
I updated your plunker here and would say, that the most important change is - referencing sub-module in the main module:
Instead of this:
angular
.module('estimate', ['ui.router', 'restangular'])
...
angular
.module('estimate.project', ['ui.router'])
...
We have to use this, i.e. reference sub module in a parent module
angular
.module('estimate', ['ui.router', 'restangular', 'estimate.project'])
...
angular
.module('estimate.project', ['ui.router'])
...
With some few other small adjustments, that should be the way. Check it working here
Related
I'm trying to use Laravel Mix, which runs webpack, to compile an angular app into one file. I get the error:
Uncaught ReferenceError: app is not defined
my webpack.mix.js:
const { mix } = require('laravel-mix');
mix.js('resources/assets/js/dependencies.js', 'public/js')
.sass('resources/assets/sass/app.scss', 'public/css');
my bundle.js :
//load angular
require('angular');
//Load Angular's plugins
require('angular-ui-router');
//Init Angular app
require('./app/app');
//Load angular controllers
require('./app/Controller/aboutController');
....
//Load angular directive
require('./app/Directive/directive');
//Load angular services
require('./app/Services/AccountService');
....
My app/app.js:
var app = angular.module('app', ['ui.router']);
app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', function ($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise('/home');
$stateProvider
.state('home', {
url: '/home',
templateUrl: 'app/View/homeView.html',
controller: 'homeController'
})
...
}]);
app.run(['$state', '$rootScope', function ($state, $rootScope) {
//APP RUN
}]);
I get the Uncaught ReferenceError: app is not defined when I call app.controller(), for example app/Controller/aboutController.js:
app.controller("aboutController", ['$scope', '$rootScope', '$http', function ($scope, $rootScope, $http) {....}
Am i missing something? If i load all the file one by one using html it works fine.
If you are defining your app's controller in separate file , then you cannot use directly app as there is no reference . You first have to refer to the module .
angular.module('app')
.controller('aboutController'....
Let me know if this work for you.
For anyone looking to do this in a more automated way for their next Laravel project, I created an article to explain how. Tested on Angular versions 4-7 with Laravel versions 5.4-5.8. I hope it helps!
I tried to migrate my Angular app from using ngRoute to uiRoute. Everything works fine except the controllers. They simple don't load like they did with ngRoute and I don't get why. As I see it from uiRoute it should work like with ngRoute but it doesn't. There is no exception thrown. I also don't find any example for a similar configuration like mine although it's very simple. I home somebody can tell me where my controller is hiding.
http://plnkr.co/edit/VGyi3AxgslgpvwBCTkXI?p=preview
So as for ngRoute the controller should be accessible through 'homepage' but it looks like it's just empty :(
;(function(angular) {
'use strict';
angular
.module('MainRouter', ['ui.router'])
.config(['$stateProvider', function($stateProvider) {
$stateProvider
.state('home', {
url: '',
views: {
"mainView": {
templateUrl: 'home.html'
}
},
controller: 'HomepageCtrl',
controllerAs: 'homepage'
});
}]);
})(angular);
When you use views option inside the state definition, then ui-router engine doesn't look for templateUrl & controller defined in state level, basically you need to provide controller & templateUrl value from the namedView definition only. In your case you should add controller in mainView definition object.
Code
.config(['$stateProvider', function($stateProvider) {
$stateProvider
.state('home', {
url: '',
views: {
"mainView": {
templateUrl: 'home.html',
controller: 'HomepageCtrl',
controllerAs: 'homepage'
}
},
});
}]);
Demo Plunkr
I created a project using Yeoman (angular-fullstack). And now I would like to know how the change/set the main view to login.html. So normally when you start the application you first get the main view where you can chose to login or register. What I want is when the application start the page starts direct on the login.html
in your app.js file located at client\app\app.js, in the angular config add the following:
$stateProvider
.run(function ($state) {
$state.go('login');
});
So it should look like:
.config(function ($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider) {
$urlRouterProvider
.otherwise('/');
$locationProvider.html5Mode(true);
$httpProvider.interceptors.push('authInterceptor');
$stateProvider
.run(function ($state) {
$state.go('login');
});
})
I realize this has been out here for a while and you likely already have a good solution, but I was recently looking at this myself and see a couple options.
One, inside app.js you could add the following code snippet under $urlRouterProvider:
.when('/', '/login')
Making your full method be something like:
.config(function ($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider) {
$urlRouterProvider
.when('/', '/login')
$locationProvider.html5Mode(true);
$httpProvider.interceptors.push('authInterceptor');
})
This would force anyone going to your base page url directly to login, unless they provide the full route to another page. However, if you intend to still use the main.html, you will then need to go into client/app/main/main.js and change the default route to:
.state('main', {
url: '/main',
templateUrl: 'app/main/main.html',
controller: 'MainCtrl'
});
So main is reachable by appending /main to the url.
Which brings me to option 2: Go into the main.js file and switch it's url to '/main' and go into login.js and switch it's url to '/'. Then anyone navigating to your base page automatically goes to the login screen but the url is viewed as just your domain without any sub page.
So client/app/main/main.js becomes:
.state('main', {
url: '/main',
templateUrl: 'app/main/main.html',
controller: 'MainCtrl'
});
And client/app/account/account.js now contains:
.state('login', {
url: '/',
templateUrl: 'app/account/login/login.html',
controller: 'LoginCtrl'
})
I have seen the other answers and so far nothing has helped me. I get this error with the following code in a file:
angular.module('myApp.page', ['ngRoute'])
.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/page/:pageId', {
templateUrl: 'page/view.html',
controller: 'PageCtrl',
resolve: {
data: function($q, $http, $routeParams) {
var deferred = $q.defer();
$http({method: 'GET', url: 'http://....' + $routeParams.pageId})
.then(function(data) {
deferred.resolve(data);
});
return deferred.promise;
}
}
})
}])
.controller('PageCtrl', function ($scope, $rootScope, data) {
//do stuff
}
And in the app.js I have this:
angular.module('myApp', [
'ui.bootstrap',
'ngRoute',
'ngTouch',
'ngResource',
'myApp.page'
]).
config(['$routeProvider', function($routeProvider) {
$routeProvider.otherwise({redirectTo: '/'});
}]).
config(['$provide', Decorate])
Everything was working correctly and I fetched the data with the HTTP method with no problems, until I started using the Q library and moved the data fetching into the config section. Any tips? None of the other answers seem to work. Thanks in advance!
You issue is due to the fact that you are using ng-controller directive to instantiate the controller PageCtrl which takes a dynamic dependency data which is only created by the router. So when you inject a dynamic dependency via router resolve and having the router instantiate the controller, you do not need to and should not instantiate the controller via ng-controller it will simply fail due to the lack of dependency availability from the injector. router will manage the instantiation of the controller and setting it up for the respective view for you.
So just remove ng-controller from your view also make sure the partial represented by the route is complete enough to represent the view related to the controller functionality. Also i have seen it is a good practice not to start with a partial view with ng-controller and instantiate with route which will help making that partial view more reusable with a different controller. Also while creating a unit test you can easily mock the dynamic dependency and feed it via the $controller service.
I have followed the instructions from https://github.com/angular-ui/ui-router/wiki/URL-Routing
but cannot get this to work properly.
I have the following:
var application = angular.module('application', ['ui.router']);
application.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider.otherwise("/test");
$stateProvider
.state('index', {
url: "/test/:param",
templateUrl: "App/Test.html",
controller: function ($scope, $stateParams) {
alert($stateParams.param);
}
});
$locationProvider.html5Mode(true);
});
Without the /:param this works as you would expect - i.e. the ui-view is correctly populated with Test.html. However, whenever I put the /:param in I get an error. The error is:
GET http://localhost:3880/test/App/Test.html 404 (Not Found)
App is the route of my angular stuff and Test.html should have a path of
http://localhost:3880/App/Test.html
which it does if not trying /:param. However, when trying /:param you can see that there is an extra /test/ in the path before /App.
Please someone help, as I would like to consume the parameter in the controller once it is correct.
You URL for this route should be like this : http://localhost:3880/test/app Where app is param.
Use absolute path for templateUrl. relative url wont work.
templateUrl: "/path/to/App/Test.html",