How to update Angular named route param after data arrives - angularjs

I have something like
angular.module('MyApp.routing', []).
config(['$routeProvider', '$locationProvider', function ($routeProvider, $locationProvider) {
$routeProvider
.when("/",
{action: "home"})
.when("/calculator/:slug/:docId/:versionId",
{action: "calculator", reloadOnSearch: false})
.otherwise({redirectTo:'/'});
}]);
in my routing file. I make a request to backend API in my controller and I want to update URL slug param.
$scope.initPage = function () {
$scope.content = {};
$scope.isPreloaderVisible = true;
http.post("calculator.getContentData.angular",
{'slug': $scope.slug, 'docId': $scope.docId, 'versionId': $scope.versionId}, getContentSuccess, getContentErrorHandler);
}
To summarize, I use URL like:
http://localhost/#/calculator//123456/
and I want to update it (without reload a whole page) to:
http://localhost/#/calculator/slug/123456/
in method getContentSuccess after request.

Any route change i believe cause view (defined in ng-view) to update itself. The reloadOnSearch is a parameter which is applicable to search parameters which are basically querystring parameters.
So if you can make your slug as part of querystring instead of url path you can stop view change.
Or else you need to look at other routing library like ui-route

Related

How to redirect using ajax in angularjs

I want to redirect a user on specific page using ajax call in angularjs. I am able to redirect using below mentioned code but when i again want to redirect user to root page i am unable to do so as the value of $window.location.href+ 'getTechnicianWorkOrder/'+woId is persisting as is:
$scope.getTechnicianWorkOrderFormURL = function(woId){
return $window.location.href + 'getTechnicianWorkOrder/'+woId;
};
Another place where i want to redirect to root page:
$scope.getAssignedListURL = function(){
return $window.location.href;
};
Note: i want to make this redirection work even in offline mode of HTML5 cache-manifest.
Using the $location service.
$location.path('/');
The answer by #prashant-palikhe is the right one, $location.path('/'); is the route to your root path. just use the dependency of $location to your controller like this:
yourapp.controller('YourController', ['$location', function($location) {
...
}
I always use the ui.router for my routes and in there you can add $urlRouterProvider.otherwise('/') for fallback in any unknown state or route.
In some cases you can add something like this in your states:
resolve : {
dataObj : ['$http', function($http) {
return $http({method : 'GET', url : '/your/ajax/endpoint'})
;}],
},
onEnter : ['dataObj', '$state', function(dataObj, $state) {
// dataObj is your ajax response object. Based on this you can redirect to a certain state of needed
$state.go('default');
}]
resolve is data that preloads data onEnter is called before entering the state. This can be used as some sort of middleware.

AngularJS force app to start from specific URL

I have a specific logic sequence in my app, and I want a simple way to force my app to start from the welcome page.
I am using this:
$urlRouterProvider.otherwise('/pages/welcome');
the problem is that otherwise just play with the unknown URLs and redirect them to the welcome, whereas I want to redirect to the welcome in all cases, even in the registered states.
Simply try location.hash = '#/'; like the following:
angular.module('app', []).config(function ($stateProvider, $urlRouterProvider) {
location.hash = '#/';
$stateProvider
.state('welcome', {
url : '/pages/welcome',
templateUrl: 'views/welcome.html',
controller : 'WelcomeCtrl'
});
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/pages/welcome');
})
i think you are redirecting to page not any state. You need to mredirect to state.
$urlRouterProvider.otherwise("/state1");

Angular UI Router - Compulsory URL parameter?

I have a couple of states the use the same controller. Some of these do not require a URL parameter while some do. How do I avoid a state from being accessible if the URL parameter is not provided?
Example:
I have 2 views or states, list and single. They both share the same controller. I have the routes mapped as follows:
state: app.list
url: /list
controller: appCtrl
state: app.single
url: /single/:id
controller: appCtrl
Now, I want single to be accessed only if the id is specified, other wise redirect to some other page. How is that possible using the same controller?
Approach 1
You can use $urlRouterProvider with when() for redirection.
app.config(function($urlRouterProvider){
// when there is an single route without param, redirect to /list
$urlRouterProvider.when('/single/:id', ['$match', '$state', function($match, $state) {
if($match.id === ""){
$state.transitionTo("app.list");
}
}
]);
});
Working demo: http://plnkr.co/edit/sEoUGGCEge0XbKp3nQnc?p=preview
Approach 2
You can check the param in controller side and redirect it to specific page
myApp.controller('MainCtrl', function($state, $stateParams) {
if($state.current.name == 'app.single' && $stateParams.id === ""){
$state.transitionTo("app.list");
}
});
Working demo: http://plnkr.co/edit/QNF1RHy4Prde4CRhNLFa?p=preview
Note: In the above demos, redirection works when your current state should not be app.single. Means, State will not change if you are in app.single state and trying without param. So go to main page, then click the link without param of single state. it will redirect to list state.

Restrict access to route with routeprovider unless variable as been set

I'm in the process of learning AngularJS, working on a more in-depth ToDo app. I'm having an issue with trying to limit access to a url or "route" using angular.
When you hit my dev url on my machine (todo.ang) it brings you to todo.ang/#/home, on this view you see the categories which have todos associated to each. EG (category = cat, cat has a todo of "feed", and "play"), when you click a category I'm calling the $scope.goToCategory function (seen in my JS fiddle) which sets a variable for my firebase ref then redirects you too /#/todo. This is working correctly.
My problem is, I don't want the user to be able to access /#/todo if the todoRef variable is still undefined. But it seems like even after $scope.goToCategory is called and todoRef is set to a firebase URL, the routerprovider never gets recalled to know that todoRef has been set to a different value so it always forces you back to /#/home.
code:
var todoRef = undefined;
if (todoRef !== undefined) {
$routeProvider.when('/todo', {
templateUrl: 'views/todo.html',
controller: 'TodoCtrl'
});
}
$scope.goToCategory = function(catId) {
test = catId;
todoRef = new Firebase("URL HERE");
$location.path('/todo');
}
I didn't include the entire file of code but if thats necessary, I can do that as well.
JSFiddle
All routes are only being set during the config phase.
what happens in your code is that 'todo' route is ignored during the initiation of ngRoute.
What you should do is to setup the route but have a resolve like so:
app.config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/todo', {
templateUrl: 'views/todo.html',
controller: 'TodoCtrl',
resolve: {
todoRef: ['$q', function($q) {
return todoRef ? todoRef : $q.reject('no ref');
}]
}
});
}]);
If 'todoRef' is undefined the route is rejected.
Also you should consider moving 'todoRef' into a service and not on global scope.
You can also listen for route errors and for example redirect to home route:
app.run(['$rootScope', '$location', function($rootScope, $location) {
$rootScope.$on('$routeChangeError', function() {
$location.path('/home');
});
}]);

AngularJS: Checking if user is on a specific route that uses params

If I have a route as such:
$routeProvider.when('/event/:id', { templateUrl: 'view/event-details.html', controller: 'EventDetailCtrl'});
Is there a way to check if the user is on the /event/:id route
Is using if ($location.path().indexOf('/event/') !== -1) a safe way to check if the user is on this route?
Of course there is. Either you can use a console.log in controller or another way you can use an ng-init in the template URL to call any function. So if the template is loaded then it will call the function and hence you get to know that the user is on that route :)
I'm not sure to fully understand what you want to achieve. Your $routeProvider relays your incoming request to a particular controller. It is inside the controller you can fully access the tokens parsed by your $routeProvider.
Declare $routeParams in your controller to access the tokens of your matched route.
$routeProvider
.when('/event/:id', { templateUrl: 'view/event-details.html', controller: 'EventDetailCtrl'});
In your controller:
.controller('EventDetailCtrl', function($scope, $routeParams) {
$scope.id = $routeParams.id;
})

Resources