Angular detect leaving a route. - javascript

I'm using Angular 1.5 and ui-router. I want to detect when a user leaves a route. I've currently got something like:
$scope.$on("$stateChangeSuccess", function () {
if (!$scope.flag) {
//...
$scope.do_work(reason);
}
});
this doesn't quite work because when the user navigates to the this route, $scope.flag is set to false and this function incorrectly fires. Is there an idiomatic way to fire a function when a user navigates away from a particular route, but not when they navigate to it?

I'd say use onExit hook of ui-router which you can specify on single state. But you can't access $scope inside it.
To deal with it, I'd say maintain service which will have shareable data. Change that shareable data from onExit hook of your desired state. Then you can access the same service inside your controller as well.
$stateProvider.state("contacts", {
template: '<h1>Dummy Template</h1>',
controller: 'myCotroller',
onExit: function(sharableService){
//... do something sharableService variable...
}
})

Related

Angular Router pass data to component

Is it a good practice to pass data with the angular router to a component or should i use an service instead?
At the moment the component gets the data like this:
this.account = activatedRoute.snapshot.data.account
There are several ways to pass data to an angular component.
For objects like user account, I would use a provider (to have it ready on component init), a service (for sharing around app) or a guard (e.g. if you want to navigate out when not logged in).
When I want to reuse the same component in different routes and give it some hints about is behavior, I would use router data.
Another use case I met is to define a global app state using the activated route(s). Each route may define its data, a service listen for router events and stores the merged state.
It helps me with large apps to have a route-based configuration for title, metas, toolbar and menus visibility, etc...
If you want to pass data through a route, here is a simple example.
Make your route to look like this:
{ path: 'todo', component: TodoComponent, data: { id:'1', name:"Todo Title"} }
Then in your Component you can do something like this:
ngOnInit() {
this.activatedroute.data.subscribe(data => {
this.todo = data;
})
}
Was this helpful?

Passing unsaved record to Ember.js route

Inside an application we allow users to create new records, related to an existing record. To achieve this, we use actions something like this:
createUser() {
var route = this;
var model = this.store.createRecord('user', {
client: route.modelFor('client'),
});
route.transitionTo('user.update', model);
},
The user.update route renders a user-form component, using the model that was passed in the transition. The same route is also used to update existing users.
The issue with this approach is as follows; when refreshing the page, the page errors because the route fails to find the respective record when querying the store (at this point, the URL is /users/null/update). Ideally I'd pass the client (or client.id) argument in the URL so that:
The page can be reloaded without issue.
The client associated with the user is set correctly.
How can I achieve this in Ember.js? I know that this can easily be done using nested routes (by nesting the user.update route inside a client route), but this doesn't make sense visually.
The relevant parts of the router are as follows:
this.route('clients');
this.route('client', {path: 'clients/:id'}, function() {
this.route('users');
});
this.route('user', {path: 'users/:id'}, function() {
this.route('update');
});
All I do in the user/update.hbs template is {{user-form user=model}}
The problem is that the model you just created has no id at that point because it is not saved, ember can´t route to a model without an id, if possible save the model before you try to transition to the route, if you don´t want to save the model because the user can cancel the action check this thread where a user had the same problem (if I understand you problem correctly), I provided a solution for that problem that I´m using in my own project
https://stackoverflow.com/a/33107273/2214998

Getting part of a URL path via Angular.js

I want to get part of a path in URL via Angular.js and i found solution:
http://mywebsite.com/one/HEREiWANT/three
first i do this:
app.config(function($locationProvider){
$locationProvider.html5Mode(true);
});
then i define my controller like this:
app.controller("mainCtrl", function ($scope,$location) {
//...
}
then with this method i can get what i want and it works!:
$scope.getURLPart = function () {
return pId = $location.path().split("/")[3]||"Unknown";
};
But this has a huge problem, right now after this changes, all of my linkes in my website doesn't work. When i click on a link, address in browsers address bar changes but i stay at the same page and redirection process doesn't happen. Why? How i can achieve what i want without with this problem?
In your state if your using state and yor passing params to your state then you can use
$stateparams to get the params
$stae.go("particular state name") to route to states

AngularJS Router invoke function when certain URL is loaded initially

I am using angular router` to track the state of my web app like this:
when('/', {
controller: "AController",
templateUrl: "APanel.html"
}).
when('/subpage/:id', {
controller: "BController",
templateUrl: "BPanel.html"
}).
And I am using Angular Service to track some shared values:
app.service('stateService', function() {
this.someSwitch = false;
this.someLongDataArray = [x, y, z];
});
Currently, before changing path to \subpage\:id url from AController, I will assign new values to members of the service, so they can be referenced in subpages.
Now the question is, if user directly launching the subpage url \subpage\:id, or hit the refresh button on browser on subpage, BController will be invoked, and I will lost the values in the service which are supposed to be prepared by AController.
I am wondering what I should do in this case. is there any way I can get called when user launch the subpage directly, so I have a chance to prepare the data? (Maybe I can watch for html onload event, but not sure that's the best answer).
Thanks
It appears, BController is dependent on AController.
Ideally, Controller should not contain any data/dom manipulaton, state maintenance. It is simply a glue between view and the $scope model.
Being said so, you need not create any such dependency between controllers. The service can be invoked from both controllers.
OR
If indeed there is a requirement that APanel.html must be loaded/initialized before BPanel.html is loaded, then you must check for some flag in BContoller and redirect user to APanel.html.
like
if(<check some flag>){
$location.path('/');
}
But then you have to find the way to redirect the user again to BPanel.html. I guess this is not a recommended approach.
I am not sure I get your question completely. But if there is a possibility that the user might hit BPanel.html directly then you should do something like this.
if(serviceExists()){
//Do your usual Bcontroller stuff here if the services was initialized
}
else{
//Show a warning/error like "Oops, something is wrong go back to '/'" OR
// Initialize services in BController
}
This should be in your BController if initializing your service before BController is that important. You basically force people to stay on AController.

Angular ngRoute conditional .when()

I'd like to implement a conditional .when(), like this:
.when('/abc', {
// if MyService.allow == true
template: '<myDirec></myDirec>'
// else
redirectTo: '/'
})
My /abc route shall be like "secured" by a variable hold in one of my services, in a stateful manner. So I want to set this very state somewhere else to true/false and the next time the user tries to get to /abc he will be served conditionally.
How can I achieve this? - with as few 3rd-party dependencies as possible
What I tried and read about:
- Simply injecting my Service in .config, which I learnt is not possible
- Read about using a provider as they can be injected. But can I use them like I use my service?
- template and templateUrl accept a function, but this didn't really help me
Thanks very much in advance!
You could use the $routeChangeStart event. It's fired when the url is changed and takes current and next as arguments something like:
$rootScope.$on('$routeChangeStart', function(event, next, current) {
if (next === 'abc') // do something;
});

Categories

Resources