I'm trying to load routes from server. when user navigate to a route via link it works perfectly, but when user hit F5 or open a route from bookmarks page will be empty. I tried $state.reload() after for loop but it causes "Cannot transition to abstract state '[object Object]'" error
var app = angular
.module("app ", ["ui.router"])
.config(function ($stateProvider, $urlRouterProvider) {
app.stateProvider = $stateProvider;
app.urlRouterProvider = $urlRouterProvider;
})
.run(function ($http, $state, $stateParams) {
$http({
method: 'POST',
url: '/Config/GetRoutes'
}).success(function (data, status) {
for (i in data.routes) {
app.stateProvider.state(data.routes[i].name, {
url: "/" + data.routes[i].name,
templateUrl: data.routes[i].url,
controller: 'sectionController'
});
}
});
})
;
Finally I found my answer!
var app = angular
.module("app ", ["ui.router"])
.config(function ($stateProvider, $urlRouterProvider) {
app.stateProvider = $stateProvider;
app.urlRouterProvider = $urlRouterProvider;
//defer intecepting
$urlRouterProvider.deferIntercept();
})
.run(function ($http, $state, $stateParams) {
$http({
method: 'POST',
url: '/Config/GetRoutes'
}).success(function (data, status) {
for (i in data.routes) {
app.stateProvider.state(data.routes[i].name, {
url: "/" + data.routes[i].name,
templateUrl: data.routes[i].url,
controller: 'sectionController'
});
}
// intecepting again
$urlRouter.sync();
$urlRouter.listen();
});
})
;
Hi I believe better solution is to write a provider to add routes dynamically, then use that in run function.
http://plnkr.co/edit/C2gXMo?p=preview
app.provider("DinamicRouteProvider", DinamicRouteProvider);
function DinamicRouteProvider($stateProvider) {
return {
$get: function( $state ) {
return {
addRoute: function (route){
$stateProvider
.state(route.name, {
url: '/' + route.name,
template: '<div><h2>This is '+route.name+'</h2></div>',
controller: 'DynCtrl'
});
console.log('State added', route)
}
};
}
};
}
Related
I am new to AngularJS I have been recently deployed to a AngularJS project. Now at backend I use Laravel and I want to know if there is a way in Angular that I can create or use the same functionality what middleware does in Laravel.
What I basically want is that I need if user is logged in then only he can move forward in the application to other pages.
I have tried something but I don't feel it is correct.
app.controller('afterLogin', function ($scope, $http, $translate,$state,toastr,$auth) {
var init = function () {
var req = {
method: 'GET',
url: baseUrl + 'username',
headers: {
'X-CSRF-TOKEN': token
}
};
$http(req)
.then(function (response) {
if(response.data.name != '')
{
$state.go('app.dashboard');
}
else
{
$state.go('core.login');
}
});
};
// and fire it after definition
init();
$scope.login = function($Login_form) {
var req = {
method: 'POST',
url: baseUrl + 'login/check',
headers: {
'X-CSRF-TOKEN': token
},
data: $scope.user
};
$http(req)
.then(function (response) {
if(response.data.status == 'success')
{
$state.go('app.dashboard');
toastr.success('', 'Logged in successfully');
}else
{
toastr.warning('', response.data.message);
}
});
};
Now the init() does is that it goes to my Laravel controller and checks is user is logged in if not then returns to login page else other wise to dashboard.
I think it is a common problem, I had to solve it too.
Basically you sohuld use the ui-router and then for the states where authentication is needed, you can call an authentication function to proof if the user is logged or not (I also check if it has the roles a to access).
I suggest the use of a service to store the User state.
myApp.config(function($stateProvider, $urlRouterProvider) {
//
// For any unmatched url, redirect to /home
$urlRouterProvider.otherwise("/home");
//
// Now set up the states
$stateProvider
.state('home', {
url: "/home",
templateUrl: "partials/home.html",
controller: 'homeController',
controllerAs: 'homeCtrl'
})
.state('contact', {
url: "/contact",
templateUrl: "partials/contact.html",
controller: 'contactController',
controllerAs: 'contactCtrl'
})
.state('profile', {
url: '/profile',
templateUrl: 'partials/profile.html',
controller: 'profileCtrl',
resolve: {
authenticated: authentic
}
});
function authentic($q, $location, $auth) {
var deferred = $q.defer();
if (!$auth.isAuthenticated()) {
$location.path('/login');
} else {
deferred.resolve();
}
return deferred.promise;
};
});
I hope it helps.
Right now i am making an AngularJS+UI router install application. But i have a problem, the problem is, that i want to disable access to the views, associated with the install application. I want to do it in resolve in the state config.
But the problem is i need to get the data from a RESTful API, whether the application is installed or not. I tried making the function, but it loaded the state before the $http.get request was finished.
Here was my code for the resolve function:
(function() {
var app = angular.module('states', []);
app.run(['$rootScope', '$http', function($rootScope, $http) {
$rootScope.$on('$stateChangeStart', function() {
$http.get('/api/v1/getSetupStatus').success(function(res) {
$rootScope.setupdb = res.db_setup;
$rootScope.setupuser = res.user_setup;
});
});
}]);
app.config(['$stateProvider', '$urlRouterProvider', function($stateProvider, $urlRouterProvider) {
$urlRouterProvider.otherwise("/404");
$stateProvider.state('db-install', {
url: "/install/db",
templateUrl: 'admin/js/partials/db-install.html',
controller: 'DBController',
resolve: {
data: function($q, $state, $timeout, $rootScope) {
var setupStatus = $rootScope.setupdb;
var deferred = $q.defer();
$timeout(function() {
if (setupStatus === true) {
$state.go('setup-done');
deferred.reject();
} else {
deferred.resolve();
}
});
return deferred.promise;
}
}
})
.state('user-registration', {
url: "/install/user-registration",
templateUrl: "admin/js/partials/user-registration.html",
controller: "RegisterController"
})
.state('setup-done', {
url: "/install/setup-done",
templateUrl: "admin/js/partials/setup-done.html"
})
.state('404', {
url: "/404",
templateUrl: "admin/js/partials/404.html"
});
}]);
})();
EDIT:
Here is what my ajax call returns:
Try this way:
$stateProvider.state('db-install', {
url: "/install/db",
templateUrl: 'admin/js/partials/db-install.html',
controller: 'DBController',
resolve: {
setupStatus: function($q, $state, $http) {
return $http.get('/api/v1/getSetupStatus').then(function(res) {
if (res.db_setup === true) {
$state.go('setup-done');
return $q.reject();
}
return res;
});
}
}
})
Then inject setupStatus in controller:
.state('setup-done', {
url: "/install/setup-done",
templateUrl: "admin/js/partials/setup-done.html",
controller: ['$scope', 'setupStatus', function ($scope, setupStatus) {
$scope.setupdb = setupStatus.db_setup;
$scope.setupuser = setupStatus.user_setup;
}]
})
I am creating a mobile app in AngularJS. I call a resource that calls an API to give me values. Everything works fine, but with slow connections or 3G $ scope not cool me, and therefore when browsing the list of items is old.
SERVICES.JS
.factory('Exercises', function($resource) {
// localhost: Local
// 79.148.230.240: server
return $resource('http://79.148.230.240:3000/wodapp/users/:idUser/exercises/:idExercise', {
idUser: '55357c898aa778b657adafb4',
idExercise: '#_id'
}, {
update: {
method: 'PUT'
}
});
});
CONTROLLERS
.controller('ExerciseController', function($q, $scope, $state, Exercises) {
// reload exercises every time when we enter in the controller
Exercises.query(function(data) {
$scope.exercises = data;
});
// refresh the list of exercises
$scope.doRefresh = function() {
// reload exercises
Exercises.query().$promise.then(function(data) {
$scope.exercises = data;
}, function(error) {
console.log('error');
});
// control refresh element
$scope.$broadcast('scroll.refreshComplete');
$scope.$apply();
}
// create a new execersie template
$scope.newExercise = function() {
$state.go('newExercise');
};
// delete a exercise
$scope.deleteExercise = function(i) {
// we access to the element using index param
var exerciseDelete = $scope.exercises[i];
// delete exercise calling Rest API and later remove to the scope
exerciseDelete.$delete(function() {
$scope.exercises.splice(i, 1);
});
};
})
APP.js
angular.module('wodapp', ['ionic', 'ngResource', 'wodapp.controllers','wodapp.services'])
// Run
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// ionic is loaded
});
})
// Config
.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
$stateProvider
.state('slide', {
url: '/',
templateUrl: 'templates/slides.html',
controller: 'SlideController'
})
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'LoginController'
})
.state('dashboard', {
url: '/dashboard',
templateUrl: 'templates/dashboard.html',
controller: 'DashboardController'
})
.state('exercise', {
url: '/exercise',
templateUrl: 'templates/exercises.html',
controller: 'ExerciseController'
})
.state('newExercise',{
url: '/newExercise',
templateUrl: 'templates/newExercise.html',
controller: 'NewExerciseController'
});
$urlRouterProvider.otherwise('/');
});
If you want to reload a part of your controller logic, every time the view is activated:
.controller('ExerciseController', function(
$q,
$scope,
$state,
Exercises,
$ionicView
) {
// reload exercises every time when we enter in the controller
$ionicView.enter(function(){
// This gets executed regardless of ionicCache
Exercises.query(function(data) {
$scope.exercises = data;
});;
});
});
Else, you can use the reload option on .state()
I am creating a mobile app in angularjs . I call a resource that calls an API to give me values. Everything works fine , but with slow connections or 3G $ scope not cool me and therefore when browsing the list of items is old
SERVICES.JS
.factory('Exercises', function($resource) {
// localhost: Local
// 79.148.230.240: server
return $resource('http://79.148.230.240:3000/wodapp/users/:idUser/exercises/:idExercise', {
idUser: '55357c898aa778b657adafb4',
idExercise: '#_id'
}, {
update: {
method: 'PUT'
}
});
});
CONTROLLERS
.controller('ExerciseController', function($q, $scope, $state, Exercises) {
// reload exercises every time when we enter in the controller
Exercises.query(function(data) {
$scope.exercises = data;
});
// refresh the list of exercises
$scope.doRefresh = function() {
// reload exercises
Exercises.query().$promise.then(function(data) {
$scope.exercises = data;
}, function(error) {
console.log('error');
});
// control refresh element
$scope.$broadcast('scroll.refreshComplete');
$scope.$apply();
}
// create a new execersie template
$scope.newExercise = function() {
$state.go('newExercise');
};
// delete a exercise
$scope.deleteExercise = function(i) {
// we access to the element using index param
var exerciseDelete = $scope.exercises[i];
// delete exercise calling Rest API and later remove to the scope
exerciseDelete.$delete(function() {
$scope.exercises.splice(i, 1);
});
};
})
APP.js
angular.module('wodapp', ['ionic', 'ngResource', 'wodapp.controllers','wodapp.services'])
// Run
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// ionic is loaded
});
})
// Config
.config(function($stateProvider, $urlRouterProvider, $ionicConfigProvider) {
$stateProvider
.state('slide', {
url: '/',
templateUrl: 'templates/slides.html',
controller: 'SlideController'
})
.state('login', {
url: '/login',
templateUrl: 'templates/login.html',
controller: 'LoginController'
})
.state('dashboard', {
url: '/dashboard',
templateUrl: 'templates/dashboard.html',
controller: 'DashboardController'
})
.state('exercise', {
url: '/exercise',
templateUrl: 'templates/exercises.html',
controller: 'ExerciseController'
})
.state('newExercise',{
url: '/newExercise',
templateUrl: 'templates/newExercise.html',
controller: 'NewExerciseController'
});
$urlRouterProvider.otherwise('/');
});
I have the following states set up:
var questions = {
name: 'questions',
url: '/questions',
views: {
'menu': {
templateUrl: function (stateParams) {
return '/Content/app/questions/partials/menu.html'
},
controller: 'QuestionsMenuController'
},
}
}
var questionsContent = {
name: 'questions.content',
parent: 'questions',
url: '/:content',
views: {
'content#': {
templateUrl: function (stateParams) {
var isNumber = !isNaN(parseFloat(stateParams.content));
return isNumber ? '/Content/app/questions/partials/detail.html' :
'/Content/app/questions/partials/content.html'
},
controller: 'QuestionsContentController'
},
}
}
and:
$stateProvider
.state(questions)
.state(questionsContent);
When I go my menu with /questions then the controller gets a list of questions and populates the $scope.questionHeaders object.
var url = '/api/Question/GetQuestionHeaders?id=0';
$http.get(url)
.success(function (data, status, headers, config) {
$scope.questionHeaders = data;
$scope.currentQuestion = $scope.questionHeaders[0].questionId;
$state.transitionTo('questions.content', { content: $scope.currentQuestion })
})
.error(function (data, status, headers, config) {
alert("Error: No data returned from " + url);
});
Following this I want to transition to the first in the list so I coded:
$state.transitionTo('questions.content', { content: $scope.currentQuestion })
However when I trace this it just stays in an infinte loop and it does not go to the new /questions/5 (when 5 is the questionHeaders[0].questionId).
Can someone give me some advice as to how I can make it transition to /questions/5 ? I am happy if it goes to the new browser href but do I need to code that directly (how) or can ui-router do this for me?
You can inject the $state service, and call it's transitionTo (go) method.
.controller('SomeController', ['$state', function($state){
$state.transitionTo('my.state', {arg:'arg'});
}]);
#Cody's question:
You can also inject the $stateParams into your controller and go to a state with args:
.controller('SomeController', ['$state', '$stateParams', function($state, $stateParams){
$state.go('my.state', {listId: $stateParams.listId, itemId: $stateParams.itemId});
}]);