Angularjs inject with additional variable - javascript

So in angular it is possible to do something like this:
function userTemplateProvider($sessionStorage, $templateRequest) {
var user = $sessionStorage.user;
}
When you call the function you simply type: userTemplateProvider; and angular will automaticly inject the services.
Now im in a situation where i need to pass variables to this function.
if i do:
userTemplateProvider($sessionStorage, $templateRequest, myvar);
And ofcourse add the myvar to the function:
function userTemplateProvider($sessionStorage, $templateRequest, myvar){
var user = $sessionStorage.user;
}
Then the two services will be empty.
So my question is how do i add variables but still inject the services
My full code:
Dashboard Module
angular.module('Dashboard',[])
.config(['$stateProvider', '$urlRouterProvider', 'JQ_CONFIG', 'USER_ROLES', 'hammerDefaultOptsProvider',
function ($stateProvider, $urlRouterProvider, JQ_CONFIG, USER_ROLES, hammerDefaultOptsProvider) {
$stateProvider
.state('dashboard', {
abstract: true,
url: '/dashboard',
templateProvider: userTemplateProvider,
resolve: {
deps: ['uiLoad',
function (uiLoad) {
return uiLoad.load([
'js/controllers/headerController.js'
]);
}]
}
})
.state('dashboard.index', {
url: '/index',
templateProvider:getTemplate,
data: {
authorizedRoles: [USER_ROLES.lb, USER_ROLES.superadmin, USER_ROLES.subadmin]
},
resolve: {
deps: ['uiLoad',
function (uiLoad) {
return uiLoad.load([
'js/controllers/chart.js',
'js/controllers/dashboard/DashboardController.js',
'js/controllers/dashboard/ClientDashboardController.js'
]);
}]
}
})
}]);
TemplateLoader
angular.module('TemplateLoader', []);
function userTemplateProvider($sessionStorage, $templateRequest) {
var templateLocation = $sessionStorage.activeUser.user.user_type.super_type_id == 1 ? 'tpl/app.html' : 'tpl/client/client.html';
return $templateRequest(templateLocation);
}
function getTemplate($state, $sessionStorage) {
var templateLocation = null;
switch ($sessionStorage.activeUser.user.user_tpe.super_type_id) {
case 1:
break;
case 2:
break;
default:
break;
}
return $templateRequest(templateLocation);
}

Creating a function specialised to myvar could work, though there is probably a convention for Angular that you could use instead.
function userTemplateProvider(myvar) {
return function($sessionStorage, $templateRequest) {
var user = $sessionStorage.user;
// can also access myvar here
};
}
Then us it as:
userTemplateProvider(myvar);

Related

ui-sref blocked from accessing controller data or view

I am having some trouble getting to the controller for my state param. I am using the correct state to link to the next view.
<td><a ui-sref="orders({customerId: cust.id})">View Orders</a></td>
In my config file I am referencing the state that name and the route params. I commented out the resolve object for now. My goal is to get into the controller then pass the correct data. Notice that I am using controllerAs
My initial thought was ({customerId: ctrl.cust.id }) However that did not change the url route.
The url is changing to match the url name but is not connecting to the controller and is not giving me the view.
(function() {
'use strict';
angular
.module('app.orders')
.config(config);
function config($stateProvider) {
$stateProvider
.state('orders',{
// params: {customerid: null},
url:'/customers:customerId',
templateUrl: './components/orders/orders.html',
controller: 'OrdersController',
controllerAs: 'ctrl',
resolve: {
customerFactory: 'customerFactory',
customerInfo: function( customerFactory, $stateParams) {
return customerFactory.getCustomers($stateParams.id);
}
}
************** my main problem is the resolve. This is blocking me from getting into the next controller. *****************
resolve: {
customerId:[ '$stateParams','customerFactory', function( $stateParams, customerFactory) {
return customerFactory.getCustomers($stateParams.id);
}]
}
})
};
})();
For now my controller is very small. I just want to connect to it. I have checked my networks tab and see GET for the files.
(function() {
// 'use strict';
angular
.module('app.orders')
.controller('OrdersController', OrdersController);
function OrdersController($stateParams) {
console.log('in');
var vm = this;
vm.title = "Customer Orders";
vm.customer = null;
}
}());
I have referenced my module in the main javascript file.
(function () {
'use strict';
angular.module('app', ['app.services',
'app.customers',
'app.orders','ui.router']);
})();
When I comment out the resolve I am able to access the controller. So I know the problem is in the resolve. Here is my service. I am making a request to a Json file with $http request and using .then
Updates Here is my refactored service call I am getting back the correct customer in the console each time.
(function() {
angular
.module('app.services',[])
.constant('_', window._)
.factory('customersFactory', customersFactory);
function customersFactory($http, $log) {
return {
getCustomers: getCustomers,
getCustomer: getCustomer
};
function getCustomers(){
return $http.get('./Services/customers.json',{catch: true})
.then(getCustomerListComplete)
.catch(getCustomerListFailed);
function getCustomerListComplete(response) {
console.log('response.data',response.data);
return response.data;
}
function getCustomerListFailed(error) {
console.log('error', error);
}
}
function getCustomer(id) {
var url = './Services/customers.json';
return $http.get(url, {
catch: true
})
.then(function(response) {
console.log('promise id',id);
var data = response.data;
for(var i =0, len=data.length;i<len;i++) {
console.log('data[i].id',data[i].id);
if(data[i].id === parseInt(id)) {
console.log('data[i]', data[i]);
return data[i];
}
}
})
}
}
}());
There is a working example with your code
It is very hard to guess what is wrong. Based on suggestion I gave you here Have a expression error in ui-sref ... your code seems to be completely valid.
I placed your stuff into this app.orders.js file (the ONLY change is templateUrl path, just for plunker purposes):
angular
.module('app.orders', ['ui.router'])
'use strict';
angular
.module('app.orders')
.config(['$stateProvider', config]);
//config.$inject = ['$stateProvider'];
function config($stateProvider) {
$stateProvider
.state('orders',{
// params: {customerid: null},
url:'/customers:customerId',
//templateUrl: './components/orders/orders.html',
templateUrl: 'components/orders/orders.html',
controller: 'OrdersController',
controllerAs: 'ctrl'
// resolve: {
// customerId:[ '$stateParams','customerFactory', function( $stateParams, customerFactory) {
// return customerFactory.getCustomers($stateParams.id);
// }]
// }
})
};
// 'use strict';
angular
.module('app.orders')
.controller('OrdersController', OrdersController);
OrdersController.$inject = ['$stateParams'];
function OrdersController($stateParams) {
console.log('in');
var vm = this;
vm.title = "Customer Orders " + $stateParams.customerId;
vm.customer = null;
}
And this is the working template components/orders/orders.html:
<div >
<h3>current state name: <var>{{$state.current.name}}</var></h3>
<h5>title</h5>
<pre>{{ctrl.title}}</pre>
...
When I call it like this:
<li ng-repeat="cust in [{id:1}, {id:2}]"
><a ui-sref="orders({customerId: cust.id})">View Orders - cust ID == {{cust.id}}</a>
</li>
Check it in action here
So, whil my previous answer was about make the state working without resolve, now we will observe few adjustments (and one fix) to make even resolve working.
There is a working plunker, extending the previous one.
FIX
The only fix, the most important change come from this definition:
angular
.module('app.services',[])
.factory('customersFactory', customersFactory);
see the plural in the factory name, the 'customersFactory'. While here:
...my main problem is the resolve. This is blocking me from getting into the next controller....
resolve: {
customerId:[ '$stateParams','customerFactory', function( $stateParams, customerFactory) {
return customerFactory.getCustomers($stateParams.id);
}]
}
we ask for 'customerFactory' (singular, no s in the middle)
Few improvements:
So, this would be our adjusted state def:
$stateProvider
.state('orders',{
// INTEGER is here used to later easily use LO_DASH
url:'/customers{customerId:int}', // int is the type
templateUrl: './components/orders/orders.html',
controller: 'OrdersController',
controllerAs: 'ctrl',
resolve: {
// wrong name with 's'
//customerId:[ '$stateParams','customerFactory',
// we use customer, because we also changed the factory
// implementation - to return customer related to
// $statePrams.customerId
customer:[ '$stateParams','customersFactory',
function( $stateParams, customersFactory) {
return customersFactory
//.getCustomers($stateParams.id)
.getCustomer($stateParams.customerId)
;
}]
}
})
Now, this is our adjusted factory, and its new method getCustomer
angular
.module('app.services', [])
.factory('customersFactory', customersFactory);
customersFactory.$inject = ['$http', '$log', '$q', '$stateParams'];
function customersFactory($http, $log, $q, $stateParams) {
return {
getCustomers: getCustomers,
getCustomer: getCustomer
};
function getCustomers() {
// see plunker for this, or above in question
}
// new function
function getCustomer(id) {
var url = "customer.data.json";
return $http
.get(url, {
catch: true
})
.then(function(response){
var data = response.data;
var customer = _.find(data, {"id" : id});
return customer;
})
;
}
}
this is our data.json:
[
{
"id" : 1, "name": "Abc", "Code" : "N1"
},
{
"id" : 2, "name": "Def", "Code" : "N22"
},
{
"id" : 3, "name": "Yyz", "Code" : "N333"
}
]
And here we have controller:
OrdersController.$inject = ['$stateParams', 'customer'];
function OrdersController($stateParams, customer) {
console.log('in');
var vm = this;
vm.title = "Customer Orders " + $stateParams.customerId;
vm.customer = customer;
}
a view to show customer
<h3>customer</h3>
<pre>{{ctrl.customer | json}}</pre>
Check it here in action

using resolve in angularjs routes

I am working on angularjs app and my config looks like this:
.config(function($stateProvider,$urlRouterProvider, $localStorage){
$stateProvider
.state('Login',{
url:'/login',
templateUrl:'templates/login.html',
controller:'LoginCtrl',
resolve: {
/* if($localStorage.userInfo === null || $localStorage.userInfo === undefined){
}else{
$scope.signInUser();
}*/
}
})
My login.html looks like this:
<form name="loginform"></form>
I want that if $localstorage.userInfo exists, do not show login.html but call $scope.signInUser function else show the form.
How do I do this using resolve of the route? Can I please get some directions?
I have tried easier ways but I ended up with 10 digest cycles reached error so I was adviced to use resolve for the purpose.
My complete route looks like this:
.config(function($stateProvider,$urlRouterProvider, $localStorage){
$stateProvider
.state('Login',{
url:'/login',
templateUrl:'templates/login.html',
controller:'LoginCtrl',
resolve: {
if($localStorage.userInfo === null || $localStorage.userInfo === undefined){
}else{
$scope.signInUser();
}
}
})
.state('Deployment',{
url:'/deployment',
templateUrl:'templates/deployment.html'
})
.state('Bill',{
url:'/bills',
templateUrl:'templates/bills.html'
})
//$urlRouterProvider.otherwise('/login');
$urlRouterProvider.otherwise(function ($injector) {
var $state = $injector.get('$state');
$state.go('Login');
});
How I achieved this
routes.js
app.config(["$routeProvider", "$locationProvider", function($routeProvider, $location) {
$routeProvider.when("/home", angularAMD.route({
templateUrl: "templates/pages/home.html",
controller: "HomeController",
controllerUrl: "app/controllers/home_controller",
resolve: {
weekendTypes: function(WeekendTypes) {
return WeekendTypes.getAll()
}
}
}));
}]);
factory.js
app.factory("WeekendTypes", ["$http", function($http) {
return {
getAll: function() {
var _apiurl = config_data.GENERAL_CONFIG.AJAX_URL + "weekend/getAll",
promise = $http({
method: "GET",
url: _apiurl
}).success(function(data, status, headers, config) {
return data
});
return promise
}
}
}])
You should use something like this
getData: function(){
var deferred = $q.defer();
$timeout(function(){
var data=localStorageService.get('description'),
deferred.resolve(data);
},3000);
return deferred.promise;
}
Had to try it by myself before sharing code.
Remove the resolve function from set local storage value as data like below
state('Login',{
url:'/login',
templateUrl:'templates/login.html',
controller:'LoginCtrl',
data : {userIfno : $localStorage.userInfo}
})
Then make use of .run function like
.run($rootScope, $state) {
$rootScope.$on('$stateChangeStart', function(toState) {
if (toState.data.userIfno === '') {
$state.go('Login', {}); //here set proper state
}
});
}
Hope this helps you.

How to redirect to another page using AngularJS?

I am using ajax call to perform functionality in a service file and if the response is successful, I want to redirect the page to another url. Currently, I am doing this by plain JS code window.location = response['message'];. But I need to replace it with AngularJS code. I have looked various solutions on stackoverflow, they used $location. But I am new to AngularJS and having trouble to implement it.
$http({
url: RootURL+'app-code/common.service.php',
method: "POST",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
dataType: 'json',
data:data + '&method=signin'
}).success(function (response) {
console.log(response);
if (response['code'] == '420') {
$scope.message = response['message'];
$scope.loginPassword = '';
}
else if (response['code'] != '200'){
$scope.message = response['message'];
$scope.loginPassword = '';
}
else {
window.location = response['message'];
}
// $scope.users = data.users; // assign $scope.persons here as promise is resolved here
})
You can use Angular $window:
$window.location.href = '/index.html';
Example usage in a contoller:
(function () {
'use strict';
angular
.module('app')
.controller('LoginCtrl', LoginCtrl);
LoginCtrl.$inject = ['$window', 'loginSrv', 'notify'];
function LoginCtrl($window, loginSrv, notify) {
/* jshint validthis:true */
var vm = this;
vm.validateUser = function () {
loginSrv.validateLogin(vm.username, vm.password).then(function (data) {
if (data.isValidUser) {
$window.location.href = '/index.html';
}
else
alert('Login incorrect');
});
}
}
})();
You can redirect to a new URL in different ways.
You can use $window which will also refresh the page
You can "stay inside" the single page app and use $location in which case you can choose between $location.path(YOUR_URL); or $location.url(YOUR_URL);. So the basic difference between the 2 methods is that $location.url() also affects get parameters whilst $location.path() does not.
I would recommend reading the docs on $location and $window so you get a better grasp on the differences between them.
$location.path('/configuration/streaming');
this will work...
inject the location service in controller
I used the below code to redirect to new page
$window.location.href = '/foldername/page.html';
and injected $window object in my controller function.
It might help you!!
The AngularJs code-sample
var app = angular.module('app', ['ui.router']);
app.config(function($stateProvider, $urlRouterProvider) {
// For any unmatched url, send to /index
$urlRouterProvider.otherwise("/login");
$stateProvider
.state('login', {
url: "/login",
templateUrl: "login.html",
controller: "LoginCheckController"
})
.state('SuccessPage', {
url: "/SuccessPage",
templateUrl: "SuccessPage.html",
//controller: "LoginCheckController"
});
});
app.controller('LoginCheckController', ['$scope', '$location', LoginCheckController]);
function LoginCheckController($scope, $location) {
$scope.users = [{
UserName: 'chandra',
Password: 'hello'
}, {
UserName: 'Harish',
Password: 'hi'
}, {
UserName: 'Chinthu',
Password: 'hi'
}];
$scope.LoginCheck = function() {
$location.path("SuccessPage");
};
$scope.go = function(path) {
$location.path("/SuccessPage");
};
}
I faced issues in redirecting to a different page in an angular app as well
You can add the $window as Ewald has suggested in his answer, or if you don't want to add the $window, just add an timeout and it will work!
setTimeout(function () {
window.location.href = "http://whereeveryouwant.com";
}, 500);
In AngularJS you can redirect your form (on submit) to other page by using window.location.href=''; like below:
postData(email){
if (email=='undefined') {
this.Utils.showToast('Invalid Email');
} else {
var origin = 'Dubai';
this.download.postEmail(email, origin).then(data => {
...
});
window.location.href = "https://www.thesoftdesign.com/";
}
}
Simply try this:
window.location.href = "https://www.thesoftdesign.com/";
The simple way I use is
app.controller("Back2Square1Controller", function($scope, $location) {
window.location.assign(basePath + "/index.html");
});
A good way to do this is using $state.go('statename', {params...}) is faster and more friendly for user experience in cases when you don't have to reload and bootsraping whole app config and stuff
(function() {
'use strict';
angular
.module('app.appcode')
.controller('YourController', YourController);
YourController.$inject = ['rootURL', '$scope', '$state', '$http'];
function YourController(rootURL, $scope, $state, $http) {
$http({
url: rootURL + 'app-code/common.service.php',
method: "POST",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
dataType: 'json',
data:data + '&method=signin'
}).success(function (response) {
if (response['code'] == '420') {
$scope.message = response['message'];
$scope.loginPassword = '';
} else if (response['code'] != '200') {
$scope.message = response['message'];
$scope.loginPassword = '';
} else {
// $state.go('home'); // select here the route that you want to redirect
$state.go(response['state']); // response['state'] should be a route on your app.routes
}
})
}
});
// routes
(function() {
'use strict';
angular
.module('app')
.config(routes);
routes.$inject = [
'$stateProvider',
'$urlRouterProvider'
];
function routes($stateProvider, $urlRouterProvider) {
/**
* Default path for any unmatched url
*/
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: '/app/home/home.html',
controller: 'Home'
})
.state('login', {
url: '/login',
templateUrl: '/app/login/login.html',
controller: 'YourController'
})
// ... more routes .state
}
})();
Using
location.href="./index.html"
or create
scope $window
and using
$window.location.href="./index.html"
(function () {
"use strict";
angular.module("myApp")
.controller("LoginCtrl", LoginCtrl);
function LoginCtrl($scope, $log, loginSrv, notify) {
$scope.validateUser = function () {
loginSrv.validateLogin($scope.username, $scope.password)
.then(function (data) {
if (data.isValidUser) {
window.location.href = '/index.html';
}
else {
$log.error("error handler message");
}
})
}
} }());
If you want to use a link then: in the html have:
<button type="button" id="btnOpenLine" class="btn btn-default btn-sm" ng-click="orderMaster.openLineItems()">Order Line Items</button>
in the typescript file
public openLineItems() {
if (this.$stateParams.id == 0) {
this.Flash.create('warning', "Need to save order!", 3000);
return
}
this.$window.open('#/orderLineitems/' + this.$stateParams.id);
}
I hope you see this example helpful as it was for me along with the other answers.

Trouble passing parameter to child state in ui-router

I have two states, one is a child of the other. One represents a list of people (people) and one for when you click on an individual person to view more details (people.detail).
My first state works as intended, and has several parameters which represent all the various server side filters and paging you could apply. The child state is a modal window, which popups as expected but my only paramater personID never makes it into $stateParams. I wonder if it's something to do the combination of the RESTful style URL and the query string style?
It is perhaps worth noting that $stateParams is populated with everything you'd expect from the parent state.
EDIT: Plunker to show what I mean - http://plnkr.co/edit/eNMIEt?p=info (note that the ID is undefined)
app.js
$urlRouterProvider.otherwise('/people');
$stateProvider
.state('people', {
url: '/people?pageNumber&pageSize&sortField&sortDirection&search&countryID&jobFunctionIDs&firmTypeIDs',
templateUrl: 'Static/js/angular/views/people-list.html',
controller: 'PeopleListController',
resolve: {
api: "api",
people: function (api, $stateParams) {
//Code ommitted
},
countries: function (api) {
//Code ommitted
},
jobFunctions: function (api) {
//Code ommitted
},
firmTypes: function (api) {
//Code ommitted
}
}
});
modalStateProvider.state('people.detail', {
url: "/{personID}",
templateUrl: 'Static/js/angular/views/people-detail.html',
controller: function () {
},
resolve: {
person: function (api, $stateParams) {
return api.people.getDetail($stateParams.personID);
}
}
});
The modalStateProvider looks like:
angular.module('myApp')
.provider('modalState', function ($stateProvider) {
var provider = this;
this.$get = function () {
return provider;
}
this.state = function (stateName, options) {
var modalInstance;
$stateProvider.state(stateName, {
url: options.url,
onEnter: function ($modal, $state) {
modalInstance = $modal.open(options);
modalInstance.result['finally'](function () {
modalInstance = null;
if ($state.$current.name === stateName) {
$state.go('^');
}
});
},
onExit: function () {
if (modalInstance) {
modalInstance.close();
}
}
});
};
})
And finally my function in my controller to transition to the people.detail state:
$scope.transitionToPersonDetail = function (personID) {
$state.transitionTo('.detail', { personID: personID }, { location: true, inherit: true, relative: $state.$current, notify: false });
};
After a lot more inspection I'm still not entirely sure why this was happening, I think it had something to do with the modalStateProvider's scope with $stateParams and the fact that the state wasn't "ready". All of this is purely speculation however.
I fixed it with this code:
$stateProvider.state('people.detail', {
url: '/{personID:int}',
onEnter: ['$stateParams', '$state', '$modal', 'api', function($stateParams, $state, $modal, api) {
$modal.open({
templateUrl: 'Static/js/angular/views/people-detail.html',
controller: function(person) {
console.log(person);
},
resolve: {
person: function() {
return api.people.getDetail($stateParams.personID);
}
}
}).result['finally'](function(result) {
$state.transitionTo('people');
});
}]
});
As far as I remember the value from 'resolve' is directly available in controller, although I think it's worth checking if controller for your child view is triggered at all
modalStateProvider.state('people.detail', {
url: "/:personID",
templateUrl: 'Static/js/angular/views/people-detail.html',
controller: function () {
console.log(person)
},
resolve: {
person: function (api, $stateParams) {
return api.people.getDetail($stateParams.personID);
}
}
});

Angular UI-Router Thinks Every URL Is Unmatched And Redirects

In my HTML, I have the following two links, but when I click them or try to enter them into the browser, my new ui-router code is redirecting them to the otherwise url I have specified. Why is this?
Folders
Clients
//Setting up route
window.app.config(function($stateProvider, $urlRouterProvider) {
// For any unmatched url, redirect to "/"
$urlRouterProvider.otherwise("/asfasfsa");
// Now set up the states
$stateProvider
.state('root', {
url: "/",
templateUrl: 'views/index.html',
resolve: { factory: setRoot }
})
.state('dashboard', {
url: "/dashboard",
templateUrl: 'views/dashboard/dashboard.html',
resolve: { factory: checkAuthentication }
})
.state('folders-show', {
url: "/folders/:folderId'",
templateUrl: 'views/dashboard/folders/view.html',
resolve: { factory: checkAuthentication }
})
.state('clients-list', {
url: "/clients'",
templateUrl: 'views/clients/list.html',
resolve: { factory: checkAuthentication }
})
});
// Check if user is logged in
var checkAuthentication = function ($q, $location) {
if (window.user) {
console.log(window.user);
return true;
} else {
console.log("Not logged in...")
var defered = $q.defer();
defered.reject();
$location.path("/");
return defered.promise;
}
};
// Set Root URLs
var setRoot = function ($q, $location) {
if (window.user) {
var defered = $q.defer();
defered.reject();
$location.path("/dashboard");
return defered.promise;
} else {
return true;
}
};
// Setting HTML5 Location Mode
window.app.config(['$locationProvider',
function($locationProvider) {
$locationProvider.hashPrefix("!");
}
]);
Sorry, simple typos on the folder and clients urls were causing the issue.
Foiled by typos again!

Categories