Pass variable from $routeProvider to View - angularjs

How can I pass a variable from $routeProvider to a view file:
app.config(['$routeProvider', function ($routeProvider) {
$routeProvider
.when('/send-money', {
templateUrl: 'partials/send-money.html',
controller: 'PageCtrl'
})
.when('/receive-money', {
someURL: 'goToSomePage',
templateUrl: 'partials/receive-money.html',
controller: 'PageCtrl'
})
}]);
As you can notice on top:
.when('/receive-money') i have declared (someURL: 'goToSomePage')
but .when('/send-money') i have not declared (someURL)
Below is the code that I would like to make it work, without taking help of controller. Is that possible ? even I am not sure something like ng-if="someURL" will work.
<div ng-if="someURL">
<a ng-href="someURL" class="nav-back"> <i class="ico-back"></i> </a>
<div>

If you don't want to use controller you can use run block to pass a reference to route service into $rootScope, from where you could check if current route has property someURL:
app.run(function($route, $rootScope) {
$rootScope.$route = $route;
});
Now in template you could use $route.current in ngIf:
<div ng-if="$route.current.someURL">
<a ng-href="someURL" class="nav-back"><i class="ico-back"></i></a>
</div>
Demo: http://plnkr.co/edit/3XUl0QprIAj1PcnnHx9Q?p=preview

Related

Trouble connecting controller using routing in AngularJS

Ill try and do my best to explain...
It doesn't seem like my controller is connecting/working properly. I'm not sure exactly why, every time I check my syntax seems correct. Here is my route declaration:
angular.module('portfolio', ['ngRoute']).config(function ($routeProvider, $locationProvider) {
$routeProvider.when('/', {
templateUrl: '/public/app/views/main.html',
controller: 'MainCtrl',
controllerAs: 'main'
}).when('/about', {
templateUrl: '/public/app/views/about.html',
controller: 'AboutCtrl',
controllerAs: 'about'
}).when('/Resume', {
templateUrl: '/public/app/views/resume.html',
controller: 'ResumeCtrl',
controllerAs: 'Resume'
}).when('/Samples', {
templateUrl: '/public/app/views/samples.html',
controller: 'SamplesCtrl',
controllerAs: 'Samples'
}).otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(false).hashPrefix('');
});
Just as an example here is my resume view:
<paper-button ng-click="changeEx()" raised>Experience</paper-button>
<paper-button ng-click="changeSkills()" raised>Skills</paper-button>
<paper-button ng-click="changeEdu()" raised>Education</paper-button>
<paper-button ng-click="changeMisc()" raised>Misc.</paper-button>
<div ng-hide="exp">
<p>Experience</p>
</div>
<div ng-show="skills">
<p>Skills</p>
</div>
<div ng-show="education">
<p>Education</p>
</div>
<div ng-show="misc">
<p>Misc.</p>
</div>
Finally, here is the declaration of the controller for the resume view:
angular.module('portfolio', []).controller('ResumeCtrl', function () {
this.exp = true;
});
Obviously, this controller is incomplete but I am simply trying to test it by using this variable.
Do not use square brackets when you are referencing a module that has already been declared. This is interpreted by Angular as declaring a new module:
angular.module('portfolio').controller('ResumeCtrl', function () {
this.exp = true;
});
The next thing I would check is your main HTML page. Do you have this directive somewhere on your page:
<div ng-view></div>
Another problem is that you are declaring controllerAs in your route as Resume, but you are using this.exp to assign your variable and also trying to reference exp in your view. You need to follow this pattern instead, or use $scope:
angular.module('portfolio').controller('ResumeCtrl', function () {
var Resume = this;
Resume.exp = true;
});
And in your view you should reference the variable using the same name you defined in controllerAs:
<div ng-hide="Resume.exp">
<p>Experience</p>
</div>
Or, alternatively, you can keep your view the same, but assign your variable using $scope:
angular.module('portfolio').controller('ResumeCtrl', function ($scope) {
$scope.exp = true;
});

ng-click does not work for linking to another view

I'm trying to link to a different page/view via ng-click and a function inside my controller. I don't do it with href because later it should be a right-click-event. But my code doesn't work. I've tried very much, and searched alot of pages but I can't find any solution. Thanks for your help :)
game.html
<div class="container" ng-controller="MainController">
<div class="handcards" ng-repeat="card in stdCards">
<a ng-click="goToCardDetail()" href="">{{ card.name }}</a>
</div>
</div>
MainController.js
app.controller('MainController', ['$scope', 'stdcards', '$location', function($scope, stdcards, $location) {
stdcards.success(function(data) {
$scope.stdCards = data;
});
$scope.goToCardDetail = function() {
$location.path('#/cards/0');
};
}]);
app.js
'use strict';
var app = angular.module('myApp', ['ngRoute']);
app.config(function ($routeProvider) {
$routeProvider
.when('/', {
controller: 'MainController',
templateUrl: 'templates/game.html'
})
.when('/cards/:id', {
controller: 'CardController',
templateUrl: 'templates/card.html'
})
.otherwise({
redirectTo: '/'
});
});
You don't need to include the # when you are calling $location.path(). So it should just be
$location.path('/cards/0');

How to pass data between angular ui-router states?

I'm developing a simple shopping cart tracking application to expand my knowledge of ui-router. I have eight different possible states, and each state has its own controller. Here is my app.config file where you can see the state definitions:
module.config(function ($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider
.state("empty", { templateUrl: "app/templates/empty.html", controller: 'emptyController', controllerAs:'vm' })
.state("initial", { templateUrl: "app/templates/initial.html", controller: 'initialController', controllerAs: 'vm' })
.state("shopping", { templateUrl: "app/templates/shopping.html", controller: 'shoppingController', controllerAs: 'vm' })
.state("shipping", { templateUrl: "app/templates/shipping.html", controller: 'shippingController', controllerAs: 'vm' })
.state("billing", { templateUrl: "app/templates/billing.html", controller: 'billingController', controllerAs: 'vm' })
.state("review", { templateUrl: "app/templates/review.html", controller: 'reviewController', controllerAs: 'vm' })
.state("confirmation", { templateUrl: "app/templates/confirmation.html", controller: 'confirmationController', controllerAs: 'vm' })
.state("error", { templateUrl: "app/templates/error.html", controller: 'errorController', controllerAs: 'vm' })
$locationProvider.html5Mode(true);
$urlRouterProvider.otherwise("/");
})
I'm trying to track the 'cart' using an object called cart, defined in a factory:
function cart() {
var factory = {};
factory.model = {};
return factory;
}
On my navbar, I have ui-sref's to change the state:
<li ui-sref-active="active"><a ui-sref="empty">Empty</a></li>
<li ui-sref-active="active"><a ui-sref="initial">Initial</a></li>
<li ui-sref-active="active"><a ui-sref="shipping">Shipping</a></li>
<li ui-sref-active="active"><a ui-sref="billing">Billing</a></li>
<li ui-sref-active="active"><a ui-sref="review">Review</a></li>
<li ui-sref-active="active"><a ui-sref="confirmation">Confirmation</a></li>
<li ui-sref-active="active"><a ui-sref="error">Error</a></li>
<li ui-sref-active="active"><a data-toggle="modal" data-target="#login-modal">Log in</a></li>
Whenever I change state, I need to transfer the entire cart.model to the new state. How can I do this? My controllers each look like this:
(function () {
"use strict";
angular.module('ShoppingCart')
.controller('emptyController', ['cart', emptyController]);
function emptyController(cart) {
var vm = this;
vm.model = cart.model;
};
}());
I'm trying to get the cart's model, but I'm not sure how I can update it on state change.
It sounds like you have the right idea of using a factory to keep the model. Since .factory and .service are singletons in angularjs, then you shouldn't have to worry about 'passing' the cart model around. Basically, anytime you enter a state, a controller instance is created that gets the cart factory injected into it. When you change states, a different controller is instantiated, and the SAME cart factory instance is injected, meaning that you should have access to the same cart.model as you had in the previous state.
If you want to move data from one state to another state you can do the following :
$state.go('toStateName', {id1 : 'dataToPass'}); //using javascript
<a ui-sref="toStateName({id1 : 'dataToPass'})">To New State</a>
and in the definition of 'toStateName' you can access these parameters using $stateParams service.
$stateProvider.state('toStateName', {
url: '/tostate',
params: {id1 : {}},
templateUrl: 'templates/send-to.html',
controller: 'SendToCtrl'
})
I hope this will do.
For more information look at the following link :
https://github.com/angular-ui/ui-router/wiki/Quick-Reference#ui-sref
I believe I figured it out. What I was doing wrong was referring to it as cart.model.whatever in my html pages. by switching to vm.model.whatever and leaving everything else the same, it started working.

Dynamic url routing with angularjs

I have something like that in my code
<ul ng-model="services">
<p ng-repeat="item in items"><b>{{ item.name }}</b>
</p>
I have for example 3 items: BMW, golf and mercedes
I want to have an url with the name of each item, like /bmw or /mercedes and all url use details.html to show the details of the selected Item.
I'm trying to understand how can I do this.
You can write a generic route like
.when('/car/:carId', {
templateUrl: 'some/path/details.html',
controller: 'someCtrl'
})
And then in the controller you can get the value of :carId using the $routeParams
You just need to code this :
<ul ng-model="services">
<p ng-repeat="item in items"><a href="/items/{{item}}">{{ item.name }}</b>
</p>
</ul>
And then capture the url in your app.js just like below:
.when('/item/:itemName', {
templateUrl: 'some/path/itemDetail.html',
controller: 'ItemCtrl'
})
And then to finish, you just need to get the item name in your controller
ItemCtrl.js :
App.controller('ItemCtrl', ['$scope', '$routeParams',
function($scope, $routeParams) {
$scope.itemName = $routeParams.itemName;
}]);
You can define paths within your module like so:
var myModule = angular.module('myModule', [])
.config(['$routeProvider', '$httpProvider', '$locationProvider', '$mdThemingProvider',
function ($routeProvider, $httpProvider, $locationProvider, $mdThemingProvider) {
$routeProvider
.when('/page1', {
templateUrl: "Views/Angular/Pages/page1.html",
contoller: "page1Ctrl"
})
.when('/page2', {
templateUrl: "Views/Angular/Pages/page2.html",
controller: "page2Ctrl"
})
.otherwise({ redirectTo: '/default' });
When the path is changed to 'page1' this module will load page1.html as the new view.
You can set up a view in an element such as:
<md-content ng-view=""></md-content>

calling a function in a different scope

I am a novice with angular so bare with will I try and articulate what I am trying to achieve.
I have two web pages; a main 'login' page and a secondary 'about' page. The about page is nothing more than a page with HTML text. I access both pages simply with a link using ng-href.
I have a service which remembers some user login details which seem to persist when I click to the about page and then back to main.
However, I have no idea how to call a function when the user clicks back to the main page. This function would be the login function within the Main Controllers scope. I would then use the users details in the service to automatically login them in and display the users information.
This thread seems quite similar, but the user seems to be at a more advanced stage than me.
Main.html
<div class="main">
<div class="content" ng-hide="login">
<form>
... login fields ...
<button ng-click="$login()">Log in</button>
</form>
</div>
<div class="content" ng-show="login">
<form>
... user info ...
</form>
</div>
<div class="footer">
<a ng-href="#/about"/>About</a>
</div>
</div>
About.hml
<div class="about">
<div class="content">
... plain HTML ...
</div>
<div class="footer">
<a ng-href='#/main'/>mAIN</a>
</div>
</div>
app.js
'
use strict';
angular.module('sguAppApp', [
'ngResource',
'ngSanitize',
'ngRoute',
'ngAnimate'
])
.constant( 'eURL', '....webpage...' )
.config(function ($routeProvider) {
$routeProvider
.when('/main', {
templateUrl: 'views/main.html',
controller: 'MainCtrl'
})
.when('/about', {
templateUrl: 'views/about.html',
controller: 'AboutCtrl'
})
.otherwise({
redirectTo: '/main'
});
});
main.js
angular.module('App')
.service('TestService', function() {
var TestService = {};
TestService.testVar1 = '';
TestService.testVar2 = '';
TestService.testVar3 = ''
return TestService;
})
.controller('MainCtrl', function ($scope, $rootScope, .... TestService) {
$scope.user = {};
$scope.user.logon = '';
$scope.user.password = '';
$scope.sData = '';
$scope.$login = function () {
$scope.loading = true;
... do stuff to testVarNs ...
}
}
.controller('AboutCtrl', function ($rootScope, $scope, TestService) {
... somehow call $login function in MainCtrl using the testVarNs in the service ...
(not sure if this is even needed)
})
The way you laid things out, either you are in the context of MainCtrl or AboutCtrl, when you navigate from one page to the other, the existing context gets destroyed and the destination one gets instanciated.
The login function should probably live in a service, this way you can call it from wherever you like.
In that way you shold inject your TestService in the controller and call the function in response to a click for example, with ng-click="TestService.$login()"
An alternative approach could be to have another controller that is in a context that wraps your MainCtrl or AboutCtrl, Say an AppCtrl that you define early in your html file, for example:
< body ng-controller="AppCtrl'>...
now, properties defined in the AppCtrl Context are visible inside the child contexts, so if you have a $login function defined there you can call it.

Resources