Resolve variable for ng-included view - angularjs

This is my app.js:
app.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'partials/home.html',
controller: 'homeController',
resolve: {
loggedUser: getLoggedUser
}
}]);
The function getLoggedUser() returns a promise which is resolved in userService when it has found the logged in user. In my index.html I include a navigation bar:
<ng-include src="'partials/navbar.html'" ng-controller="homeController"></ng-include> // Navbar
<div ng-view></div> // Angular views
The problems are:
ng-controller cannot be used with resolve since it creates an AngularJs error of 'unknown provider'. Therefore, the ng-include creates trouble for the '/' route.
I cannot/do not know how to specify a resolve for the navbar since it has no route, but is included in every view in index.html. And the navbar needs to show the name of the logged in user.
EDIT1:
I tried an ugly solution, by returning myPromise.$$state.value in homeController and removing the resolve {...}. However, it feels like I shouldn't use the $q promises like this. Any other suggestions?
EDIT2:
What I mean is that the loggedUser is unknown because of ng-controller="". Here is an explanation: AngularJS, resolve and unknown provider.

I think the reason why you get an error about 'unknown provider' is that you need to inject the service userService into the resolve function :
app.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.when('/', {
templateUrl: 'partials/home.html',
controller: 'homeController',
resolve: {
loggedUser: function(userService) {
return userService.getLoggedUser();
}
}
}]);

You can separate the navbar from the rest of your app.
Use something like
<body>
<div ng-controller = "navbarController as nav">
<div ng-show=" userIsLoggedIn"> <!-- show navbar only if true -->
<!-- navbar markup-->
</div>
</div>
<div ng-view> <!-- display other templates here --> </div>
</body>
You can then use a service in which us store the login status and credentials of the user. As services can be accessed app wide, you can access its data (like the username) in your navbarController.

Related

Error 404 when serving files in angularjs and node app

I have
<base href="/!#/">
at the top of my index.html file. When I go to URL http://localhost:5000/ everything works fine, it instantly add #!/ so the URL is http://localhost:5000/#!/ and page display as expected.
At the server side I have following code which should allow me to use my files
app.use(express.static(path.join(__dirname, 'public')));
Structure of my files is something like:
bookApp(folder)
server.js
public(folder)
index.html
app.js(ngRoute)
views(folder)
css(folder)
controllers(folder)
and my AngularJS routing is:
(function () {
'use strict';
angular
.module('app', [
'ngRoute'
])
.config(config);
function config ($routeProvider) {
$routeProvider
.when('/', {
controller: 'PostsCtrl',
templateUrl: 'views/posts.html'
})
.when('/register', {
controller: 'registerCtrl',
templateUrl: 'views/register.html'
})
.when('/login', {
controller: 'loginCtrl',
templateUrl: 'views/login.html'
})
.otherwise('/');
}
})();
The very first page (views/posts.html) load as expected but when I click
<li>Sign in</li>
the URL is http://localhost:5000/login not as like I thought http://localhost:5000/!#/login.
and it display:
Cannot GET /login
when I manually change URL to http://localhost:5000/#!/login it works fine.
How to fix this behavior?
The only solution I see is to get rid of <base> tag and in every link manually in href directive add !# before slash.
It looks like you are forgetting the ng-view directive: <div ng-view></div> which is the container for the content that is provided by your routing. Place this above your script if you have everything contained in one file.
You can also try:
<ng-view></ng-view>
<div class="ng-view"></div>
Is there any particular reason you are still using Angular 1? I know this isn't technically answering your question, but I would highly recommend that you start using the latest Angular. You can still keep legacy code but it will make a lot of what you are doing a lot cleaner and clear.

My controller is interfering with my ui-routing

I had a working prototype of state views with hardcoded values, but when I tried to include a controller, it breaks the ui-sref links, and they don't seem to point to anything. I can remove the ng-controller attribute and they work again though, and display just fine.
I've also tried attaching ng-controller to a div in the template as well, foregoing a controller in index.html altogether, and while that doesn't break the link, I can't get any expressions in the template to work, and having a controller would be sub-optimal for the purposes of my app if I could avoid it.
What limitations of controllers and views am I misunderstanding?
index.html snippet
<div class="main" ng-controller="MainCtrl">
<a ui-sref="StateA">AAAAA</a>
<div ui-view></div>
</div>
app.js
var app = angular.module('app', ['ui.router']);
app.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('StateA', {
url: "/a",
templateUrl: "views/a.html",
controller: "MainCtrl"
})
});
MainCtrl.js
app.controller("MainCtrl", [$scope, function($scope, paramGroups) {//empty controller//}]);
Apart from some of the syntax errors you have going on your fundamental problem is understanding of how ui-router works.
When you define something like:
.state('StateA', {
url: "/a",
templateUrl: "views/a.html",
controller: "MainCtrl"
})
It means, that when you go to route /a the partial a.html that will get rendered in your ui-view will get the scope for MainCtrl.
There's no point defining ng-controller='MainCtrl' on the element that is parent of ui-view because, ui-view will automatically get the scope for MainCtrl when the route resolves.
Route breaks when you declare that ng-controller because you are trying to nest same controller inside itself.

$stateProvider does not redirect. ngRoute was working fine. But had to switch to angular-ui-router for multiple and nested views loading

Developing a POC for an application.
Technologies being used : ASP.Net MVC4 and AngularJs.
Initialy while getting started i was using ngRoute and $routeProvider. The links used to redirect to the server to the required controller action and pages used to load in the div marked with ng-view directive. But my requirement was to laod multiple and nested views. So, had to switch to $stateProvider which supports such requirements.
Now i am facing the issue of the links not getting redirected. The "Project" link redirects but the "Opportunity" does not. My requirement is to load a view inside the first div and then one more view into AddOpportunityContainer
Following below is the code which i had written. Can anyone help me what wrong i have been doing. Had already spent quite an amount of tme on it.
Referred Libraries:
angular.js and angular-ui-router.js
The Code:
var GuidanceApp = angular.module('GuidanceApp', ['ui.router']);
var configFunction = function ($stateProvider, $httpProvider, $locationProvider) {
$stateProvider
.state('Projects', {
url: '/Projects',
templateUrl: 'Projects/Index'
})
.state('Opportunity', {
url: '/Opportunity',
templateUrl: '/Opportunity/Index',
views:{
"AddOportunityContainer": {
templateUrl: '/Opportunity/Create'
}
}
});
}
configFunction.$inject = ['$stateProvider', '$httpProvider', '$locationProvider'];
GuidanceApp.config(configFunction);
Following is the HTML of home page. And as you can see, the last div is marked with ui-view now instead of ng-view as in case of ngRoute and $routeProvider
<div>
<ul>
<li>Projects</li>
<li>Opportunity</li>
<li>Adjustments</li>
<li>Summary</li>
</ul>
</div>
<div ui-view></div>
Different partial view to be loaded on click of Opportunity link.
<h2>Opportunity-Index</h2>
<div ui-view="AddOportunityContainer"></div>
Your link for anchor element should be corrected as below without leading '/':
<li>Projects</li>

Angular Service method is called twice?

I have a simple service:
angular.module('sf').factory 'sfStatic2', ->
{
doSomething: ->
console.log('called-x')
43
}
angular.module('sf').controller 'UserRegisterCtrl', ($scope,sfStatic2) ->
$scope.timezoneX = sfStatic2.doSomething()
In the console I see two times 'called-x', do you know why is this happening ? I am using angular 1.3.15
This could be occuring due to controller being called two times.
Make sure you are writing controller only once.
write either in ng-controller or in your config route.
route config (usually, app.js):
app.config(['$routeProvider', function($routeProvider){
$routeProvider.when('/',
{
templateUrl: 'pages/home.html'
//Remove controller from here
});
}]);
home.html
<!-- Add the ng-controller in your view -->
<div ng-controller="MyItemsController">
<!-- Your stuff -->
</div>

Reading URL Query string

I have the following URL:
http://myUrl.com/#/chooseStyle?imgUpload=6_1405794123.jpg
I want to read the imgUpload value in the query string - I'm trying:
alert($location.search().imgUpload);
But nothing alerts, not even a blank alert - but console reads:
$location is not defined
I need this value to add into a controller to pull back data, and also to carry into the view itself as part of a ng-src
Is there anything I'm doing wrong? this is my app config:
capApp.config(function($locationProvider, $routeProvider) {
$locationProvider.html5Mode(false);
$routeProvider
// route for the home page
.when('/', {
templateUrl : '/views/home.html',
controller : 'mainController'
})
// route for the caption it page
.when('/capIt', {
templateUrl : '/views/capIt.html',
controller : 'mainController'
});
}):
This is the view:
<div class="container text-center">
<h1 class="whiteTextShadow text-center top70">Choose your photo</h1>
</div>
<script>
alert($location.search().imgUpload);
</script>
Main controller:
capApp.controller('mainController', function($scope) {
$scope.message = 'Whoop it works!';
});
My end goal is that I can find a solution to capturing and re-using data from the query string.
I will also mention, this is only my first week in Angular, loving it so far! A lot to learn...
<script>
alert($location.search().imgUpload);
</script>
You're making two mistakes here:
executing code while the page is loading, and the angular application is thus not started yet
assuming $location is a global variable. It's not. It's an angular service that must be injected into your controller (or any other angular component). This should cause an exception to be thrown and displayed in your console. Leave your console open always, and don't ignore exception being thrown.
You should not do this
<script>
alert($location.search().imgUpload);
</script>
// you need to inject the module $location
//(either in service, or controller or wherever you want to use it)
// if you want to use their APIs
capApp.controller('mainController', function($scope, $location) {
$scope.message = 'Whoop it works!';
//use API of $location
alert($location.search().imgUpload);
});

Resources