How to access URL parameters in named views using ui-router - javascript

I am clicking on an anchor tag boofing and trying to access the URL parameters values into my app.js but I am getting null values for $scope, $stateParam, $state.
app.js
...
.state('bar', {
url: '/boof?sid&qid',
views: {
'': {
templateUrl: 'partials/a.html',
controller: function ($scope, $stateParams, $state) {
//not getting $scope, $stateParams, $state
}
},
'foo#bar': {
templateUrl: 'partials/b.html',
controller: function ($scope, $stateParams, $state) {
//not getting $scope, $stateParams, $state
}
},
...
}
})
...
a.html
<div ui-view="foo"></div>
<div ui-view="xyz"></div>
b.html
<div>
//stuff using data from $scope, $stateParams, $state
</div>
Could somebody help me understand why am I getting null values for $scope, $stateParams, $state.
Also, could I just do a controller: 'myController' as below and access the $stateParams, $state in myController?
app.js
...
.state('bar', {
url: '/boof?sid&qid',
views: {
'': {
templateUrl: 'partials/a.html',
controller: 'myController'
}
},
'foo#bar': {
templateUrl: 'partials/b.html',
controller: 'myController'
}
},
...
}
})
...
myApp.controller("myController", ['$scope', '$http', '$stateParams', '$state', function($scope, $http, $stateParams, $state){
//accessing $stateParams and $state here
} ]);
I tried to do it, but I was getting a null value for both $stateParams and $state.

Related

AngularJS Routing to different page with different controller

I have two HTML pages. One is the exam.html and other is result.html. On certain condition in the controller ExamCtrl of exam.html, I route to result.html using $location.path. But however, on the result page, the controller ResultCtrl doesn't seem to load though I have added it in the config file.
angular config file:
angular.module('exam').config(['$stateProvider',
function ($stateProvider) {
// Exam state routing
$stateProvider
.state('exam', {
abstract: true,
url: '/exam',
template: '<ui-view/>'
})
.state('exam.list', {
url: '',
templateUrl: 'modules/exam/client/views/exam.client.view.html',
controller: 'ExamCtrl'
})
.state('/result', {
url: '/result',
templateUrl: 'modules/exam/client/views/exam-result.client.view.html',
contoller: 'ResultCtrl'
});
}
]);
ExamCtrl:
angular
.module('exam')
.controller('ExamCtrl', ['$scope', '$stateParams', '$location', 'Authentication', '$http',
function ($scope, $stateParams, $location, Authentication, $http) {
$scope.submitAnswer = function (selected) {
//some code
if (qtnCounter > 5) {
// loads the result page.
$location.path('/result');
} else {
$scope.getQues();
}
};
}
]);
ResultCtrl:
angular
.module('exam')
.controller('ResultCtrl', ['$scope', '$stateParams', '$location', 'Authentication', '$http',
function ($scope, $stateParams, $location, Authentication, $http) {
console.log('ResultCtrl');
}
]);
result.html:
<body ng-controller="ResultCtrl">
<h1>Result page!</h1>
</body>
Insted of using $location use the $state to change to a given state in your app.
Inject the $state in the controller and then call the transitionTo() which will load the view and setup the controller
angular
.module('exam')
.controller('ExamCtrl', ['$scope', '$state', 'Authentication', '$http',
function ($scope, $state, Authentication, $http) {
$scope.submitAnswer = function (selected) {
//some code
if (qtnCounter > 5) {
// loads the result page.
$state.transitionTo('/result');
} else {
$scope.getQues();
}
};
}
]);

Cannot read property 'defaults' of undefined when trying to add token inside stateChangeStart

My objective is to to send a token as Authorization header to each of the service calls in my application.
Here is my code
'use strict';
var properties = {};
angular.module('nbaportalUi', ['ngAnimate', 'ngCookies', 'ngTouch', 'ngSanitize',
'ngResource', 'ui.router', 'ui.bootstrap', 'uiSwitch'])
.run(['$rootScope', '$state', '$window', '$cookies', function ($rootScope, $state, $window, $cookies, $http) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams, options) {
$http.defaults.headers.common.Authorization = 'Bearer carmeloanthony' ;
});
}])
.config( function($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider
.otherwise('/home');
// note the 'abstract:true' state below - it can not get activated
// it is activated implicitly when one of its descendants are activated
$stateProvider
.state('app', {
abstract: true,
controller: 'MainCtrl',
templateUrl: 'app/main/main.html'
})
.state('app.overview', {
url: '/overview',
templateUrl: 'app/overview/summary.html',
controller: 'OverviewCtrl'
})
.state('loginPage', {
url: '/login',
templateUrl: 'app/login/login.html',
controller: 'LoginCtrl'
})
.state('errorPage', {
url: '/error404',
templateUrl: 'app/404.html'
});
})
.constant('ENV', {
'name': 'dev',
'apiEndpoint': 'https://api.blah.com/nba/v1/team/'
})
;
I am inserting $http.defaults.headers.common.Authorization = 'Bearer carmeloanthony' ; inside $stateChangeStart because it is called every time.
However when i attempt to this i get an error saying
angular.js:11706 TypeError: Cannot read property 'defaults' of undefined
at index.js:43
This error is refering to the following line of code -> $http.defaults.headers.common.Authorization = 'Bearer carmeloanthony' ;
However when i try to add the token as authorization adder outside stateChangeStart as follows it works:
'use strict';
var properties = {};
angular.module('nbaportalUi', ['ngAnimate', 'ngCookies', 'ngTouch', 'ngSanitize',
'ngResource', 'ui.router', 'ui.bootstrap', 'uiSwitch'])
.run(['$rootScope', '$state', '$window', '$cookies', function ($rootScope, $state, $window, $cookies) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams, options) {
});
}])
.config( function($stateProvider, $urlRouterProvider, $locationProvider) {
$urlRouterProvider
.otherwise('/home');
// note the 'abstract:true' state below - it can not get activated
// it is activated implicitly when one of its descendants are activated
$stateProvider
.state('app', {
abstract: true,
controller: 'MainCtrl',
templateUrl: 'app/main/main.html'
})
.state('app.overview', {
url: '/overview',
templateUrl: 'app/overview/summary.html',
controller: 'OverviewCtrl'
})
.state('loginPage', {
url: '/login',
templateUrl: 'app/login/login.html',
controller: 'LoginCtrl'
})
.state('errorPage', {
url: '/error404',
templateUrl: 'app/404.html'
});
})
.constant('ENV', {
'name': 'dev',
'apiEndpoint': 'https://api.blah.com/nba/v1/team/'
})
;
angular.module('nbaportalUi').run(function($http) {
$http.defaults.headers.common.Authorization = 'Bearer carmeloanthony' ;
});
I would prefer to get my first approach working. I appreciate any help I can get.
You have to include the $http service as following (your forgot to put in the array) :
.run(['$rootScope', '$state', '$window', '$cookies','$http', function ($rootScope, $state, $window, $cookies, $http) {

Avoid a repeated scope variable in different controllers in AngularJS

I've got few controllers working with different templates:
curryApp.config(['$routeProvider',
function($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'table_index.html',
controller: 'CurryListCtrl'
}).
when('/cities/:cityId/', {
templateUrl: 'template-total.html',
controller: 'CurryDetailCtrl'
}).
when('/cities/:cityId/mobile/', {
templateUrl: 'template-mobile.html',
controller: 'CurryMobileCtrl'
}).
when('/cities/:cityId/online/', {
templateUrl: 'template-online.html',
controller: 'CurryOnlineCtrl'
}).
All of theses controllers have $scope variable called cities
For example, the first one:
curryControllers.controller('CurryDesktopCtrl', ['$scope', '$routeParams', '$http', '$route',
function($scope, $routeParams, $http, $route) {
$scope.cityId = $routeParams.cityId;
$http.get('json/cities.json').success(function (data) {
$scope.cities = data;
...
The second one:
curryControllers.controller('CurryOnlineCtrl', ['$scope', '$routeParams', '$http', '$route',
function($scope, $routeParams, $http, $route) {
$scope.cityId = $routeParams.cityId;
$http.get('json/cities.json').success(function(data) {
$scope.cities = data;
...
Is it okay to have repeated $scope variables in different controllers?
How should I refactor the code in order to escape duplicates?
If cities are not going to change for every controller use services like below
Your service should look like below
app.service('myService',function($http,$q){
var cities=null;
this.getCities=function()
{
var deferred = $q.defer()
if(this.cities==null){
$http.get('json/cities.json')
.then((response) => {deferred.resolve(response);cities=response;})
.catch((error) => deferred.reject(error))
}
else { deferred.resolve(cities)}
return deferred.defer
})
});
Use the above service in the controller
app.controller('ctrl',function($scope,myService){
myService.getCities().then(function(data){ $scope.cities = data;})
})
You can create a factory:
.factory('citiesFactory', function($http) {
function getCities(){
// return promise from function
return $http.get("json/cities.json");
}
return {
getCities: getCities
}
});
then in your controller:
curryControllers.controller('CurryDesktopCtrl', ['$scope', '$routeParams', '$http', '$route', 'citiesFactory'
function($scope, $routeParams, $http, $route, citiesFactory) {
$scope.cityId = $routeParams.cityId;
citiesFactory.getCities().then(function(response){
$scope.cities = response.data;
});
...
You should do create a factory like this. Forgive the syntax, but you get the idea.
app.factory('Cities', function ($http) {
return {
'getData': function() {
$http.get('json/cities.json').success(function (data) {
return data;
}
.error(function(error){
return [];
}
}
};
}]);
and in your controller inject the factory and get the data
curryControllers.controller('CurryOnlineCtrl', ['$scope', '$routeParams', '$http', '$route', 'Cities'
function($scope, $routeParams, $http, $route) {
$scope.cityId = $routeParams.cityId;
$scope.cities = Cities.getData();
...
If the cities json is common for all the controllers.
One option would be to move the common object used across controllers into rootscope refer.
Other option would be to store the cities json in the service itself read here.

Angular, $route.current returning undefined, but $route has a .current property

I have a controller:
app.controller('NavbarController', ['$scope', '$route', function($scope, $route) {
console.log($route);
console.log($route.current)
}]);
But when I try to use $route.current I get undefined, I have no idea why as $route has the propety when I console.log($route)
I have
.when('/', {
templateUrl: '/home',
controller: 'HomeController',
activeTab: 'home'
}).
I need to access $route.current.$$route.activeTab so I can get the variable and set the appropriate class.
Full Controller:
var app = angular.module('PugIt', ['ngRoute', 'ui.bootstrap'])
app.config(function($routeProvider) {
$routeProvider
.when('/', {
templateUrl: '/home',
controller: 'HomeController',
activeTab: 'home'
}).
when('/help', {
templateUrl: '/help',
controller: 'HelpController',
activeTab: 'help'
}).
when('/donate', {
templateUrl: '/donate',
controller: 'DonateController',
activeTab: 'donate'
}).
when('/server', {
templateUrl: '/server',
controller: 'ServerController',
activeTab: 'server'
}).
when('/server/new', {
templateUrl: '/server/new',
controller: 'NewServerController',
activeTab: 'serverNew'
}).
otherwise({
redirectTo: '/'
});
});
app.controller('HomeController', ['$scope', '$route', function($scope, $route) {
}]);
app.controller('HelpController', ['$scope', '$route', function($scope, $route) {
}]);
app.controller('DonateController', ['$scope', '$route', function($scope, $route) {
}]);
app.controller('ServerController', ['$scope', '$route', function($scope, $route) {
}]);
app.controller('NewServerController', ['$scope', '$route', function($scope, $route) {
}]);
app.controller('NavbarController', function($scope, $rootScope) {
$route.activeTab = $route.current.$$route.activeTab;
});
Which then sets the active class with:
// Navbar
<div ng-controller="NavbarController">
<li ng-class="{'active': activeTab == 'home'}">Home</li>
</div>
// End of Navbar
<div ng-view></div>
Since you need to keep track of your routes, you can definitely $watch for changes:
.controller('NavbarController', function($scope, $route) {
$scope.$route = $route;
$scope.$watch("$route.current.$$route.activeTab", function(v){
$scope.activeTab = v;
}
});
But this creates an unnecessary $watch. It's not too bad since it is only one, but it would be cleaner to listen to a $routeChangeSuccess event instead:
.controller('NavbarController', function($scope, $route) {
$scope.$route = $route;
$scope.$on("$routeChangeSuccess", function(event, current, previous){
$scope.activeTab = current.$$route.activeTab;
}
});
Most probably the current route is not set when the NavController is loaded.
What you can do in your NavController is to watch over $route.current, and
when it gets set\changed, implement the logic in the watch handler
$scope.$watch(function() {
return $route.current;
},function(newValue,oldValue) {
//implement logic here
});

$state.go not working - Error : $state isnot defined

Hi im Very new Angulay js Ionic development. im trying to basic navigation when button is clicked. but im getting this error when i click the button in Firebug console . i want to navigate to the search page after it clicked
Error : $state isnot defined
Here my App.js Code
.config(function($stateProvider, $urlRouterProvider) {
$stateProvider
.state('signin', {
url: "/sign-in",
templateUrl: "templates/sign-in.html",
controller: 'AppCtrl'
})
.state('app', {
url: "/app",
abstract: true,
templateUrl: "templates/menu.html",
controller: 'AppCtrl'
})
.state('app.search', {
url: "/search",
views: {
'menuContent': {
templateUrl: "templates/search.html"
}
}
})
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/sign-in');
});
here my Controller
angular.module('starter.controllers', [])
.controller('AppCtrl', function($scope, $ionicPopup, $timeout, $ionicModal) {
$scope.signIn = function(user) {
//console.log('Sign-In', user);
$state.go('app.search');
};
})
My HTML button is
<button class="button button-block button-positive" id="login-btn" ng-click="signIn(user)" type="submit">Log in</button>
You should also get in the habit of properly injecting your dependencies. It should look like this (including the $state injection):
.controller('AppCtrl',['$scope', '$ionicPopup', '$timeout', '$ionicModal', '$state', function($scope, $ionicPopup, $timeout, $ionicModal, $state) {
$scope.signIn = function(user) {
//console.log('Sign-In', user);
$state.go('app.search');
};
}])
Just make sure the order of injections in the quotes are in the same order as the order of your parameters in the following function.

Categories

Resources