Using Angular 2 RC5 router, how can I navigate, given an ActivatedRouteSnapshot? - javascript

Use Case
The user can access certain parts of my site without being logged in. If they click a download button and are logged in, the download starts automatically. However, if they click the download button and are not logged in, I'd like to prompt them to login. Once they're logged in, I'd like them to be sent straight back to the route they were previously on.
How I'm trying to accomplish it
When an "anonymous" user clicks a download button, they're given a modal with a prompt to login. If they decide to login, I'll stash some object in local storage (was thinking an ActivatedRouterSnapshot would do?). After login, I'll check to see if there's an object stored under stashedRoute in local storage. If there is, I'll use it to navigate them back to their original route!
What I want to do
Given:
import { Router } from '#angular/router';
and
private someRoute: ActivatedRouterSnapshot;
constructor(private _router: Router) {}
I want to:
this._router.navigate(someRoute)
The question
What is the syntax for either doing the above, or getting the same functionality for storing a route and re-navigating to it?

i think you need some thing like a history for going back in routes
you can use code below as described here
import {Component} from '#angular/core';
import {Location} from '#angular/common';
#Component(...)
class AppCmp {
constructor(private _location: Location) {
}
backClicked() {
this._location.back();
}
}

I had a similar issue and solved it by the following. flatten is from lodash and route is your ActivatedRoute. It's not great, but it works for now. You might want to use flattenDeep instead to accommodate for deeply nested routes.
const route = flatten(route.pathFromRoot.map(r => r.url)).map(s => s.path);
this.router.navigate(route);

Related

Should I use window.location.replace('/') or window.location.href=window.location.origin in the process of logging out?

In a logout button, should I be using window.location.replace('/') or window.location.href=window.location.origin. What is the difference between these two methods? I know that both of them clear the current href from the history, so the url won't be accessible to the user after logging out using either of them.
if you are using next.js you can use next/router which is a better approach to it.
import { useRouter } from 'next/router'
const router = useRouter()
//and then you can do it like this
router.replace('/')
//or
router.push('/')

How to refresh a component declared in HTML everytime its parent component is visited using the same URL?

For example, I have 2 components, A and B.
In A.component.html there is code as follow
<B></B>
A is accessed via router, and I want B to be refreshed, by calling B's ngOnInit(), everytime A is visited, even with the same URL.
I have
set onSameUrlNavigation: 'reload' in RouterModule.forRoot
runGuardsAndResolvers: 'always' in A's path
subscribe to router.events in B's constructor as shown below
this.navigationSubscription = this.router.events.subscribe((e: any) => {
if (e instanceof NavigationEnd) {
this.ngOnInit();
}
});
But it doesn't work. B is not refreshed.
I guess that is because B is NOT accessed via router directly but as a child of A?
Then how to refresh B everytime A is visited?
Thanks in advance!
This can be done using onSameUrlNavigation.
you can Define what the router should do if it receives a navigation request to the current URL.
app.module.ts
#NgModule({
imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: 'reload' })]
})
class MyNgModule {}
Now,Inject your router
app.component.ts
import { Router } from '#angular/router';
constructor(private router: Router) {
this.router.routeReuseStrategy.shouldReuseRoute = () => false;
}
DEMO
More Detail
I don’t think onnginit is suppose to be called directly. Avoid that.
Would listening to this.router.events.subscribe inside B solve the problem?
If not, use a service to share data between them. Inside the service you could have a subject that B could subscribe to. On navigation in A you trigger the subject
It turned out that the problem is in the Apollo GraphQL library.
It was using cache so no request was made toward BE...

React: change url without rerender; using window.history?

I have a "settings" page in my react app. The page has several tabs rendering different parts of settings.
It would be better UX if a user can share urls with other users.
What I want is (inside "settings" page):
user A clicks a tab
url changes with a #tabname appended
user A send that url to user B, and user B open that url
user B sees the same tab as user A
But with react router, the whole page re-renders if the url changed:
import { withRouter } from "react-router-dom"
const MyComp = (props) => {
...
const onTabChange = () => {
// append #tabname here
props.history.replace(...); // or `push`
...
}
...
export default withRouter(MyComp)
}
After a lot of searches, I found a solution to use window.history:
const onTabChange = () => {
window.history.pushState(null, null, "#tabname");
...
}
This does the trick, but little information and explanation, and I'd love to know the consequences of using this trick.
Is this a valid solution (for a react app)? Will this cause any problem?
(PS. I know how to parse a url)
More details:
To be more specific, there is a AuthChecker wrapper for all pages. When react router's location changes, it checks for the route's allowed auths and current user's auth.
I've tried /path/:id and everything but all change location, so auth checked and page rerendered.
And I've given up a solution in react router and just want to know: is it safe to change url with window.history in a react app using react router to manage routes?
this question is already answerd at this post.
so it says window has a property called history and there is a method on history which helps you update the history state without react-router-dom understanding it.
like this:
window.history.replaceState(null, 'New Page Title', '/new_url');

Aurelia/TS Activate does not update current view

What do I want to achieve
I want to update my current view based on an Id. So say that I have side navigation with the following tabs:
Customer A
Customer B
Customer C
What I want is that the user can click on Customer A and that the current customer view gets updated based on the Customer Id.
What is my problem achieving this
I thought the best way to solve this issue was to navigate to the page and provide the Id directly as follows:
router.navigateToRoute("customer", { currentCustomerId });
Then on the Customer page I am receiving the Id in the activate method as following:
public activate(params) {
this.currrentCustomerId = params.currentCustomerId;
}
Actually, this is working the first time you navigate to a customer. But when I am clicking on another Customer page, the view does not get updated because the activate method does not get triggered for a second time. It is only working if I navigate to another page (not customer page) and go back or simply refresh the whole page.
So what can I use to achieve what I want? I reckon that I have to use something else than activate()?
I appreciate it if someone could give me some insight into this issue.
Regards.
This is due to the default activation strategy wherein, if the URL only changes in terms of a parameter value, the component is reused and hooks are not invoked.
To obtain the desired behavior, you can customize the this behavior at the component level or the route level.
At the component level:
import {activationStrategy} from 'aurelia-router';
export class CustomerComponent {
determineActivationStrategy() {
return activationStrategy.replace;
}
activate(params: {currrentCustomerId: string}) {
this.currentCustomerId = params.currentCustomerId;
}
}
At the route level:
import {Router, RouterConfiguration} from 'aurelia-router';
export class App {
configureRouter(config: RouterConfiguration, router: Router) {
config.map([{
name: 'customer',
moduleId: './customer',
route: 'customer/:currentCustomerId',
activationStrategy: 'replace'
}]);
this.router = router;
}
}

Loosing data upon navigation, page change

My app displays a profile name that can be edited. When i edit it it changes, great. When i navigate and come back, the data reset's.
I've tried holding the data (profile name) as a String variable, I've tried holding the data as a list and displaying the name with String[0] to display the unshifted profile name.
First go
<h3>{{profileService.profileName}}'s Profile</h3>
this.profileService.changeName(this.pName);
changeName(data){
this.profileName = data;
}
Second go
<h3>{{profileService.profileNames[0]}}'s Profile</h3>
this.profileService.changeName(this.pName);
changeName(data){
this.profileNames.unshift(data);
}
So, again, this updates initially when I go from edit-page to home-page. When I go to another page and return, the updated profile name is MISSING. Thanks!
Have you made sure that:
The service is provided for both the home page and the edit page?
This can be done by:
in app.module.ts (I guess you want your changes to persist for the whole application)
#NgModule({
declarations:[
//your components here
],
imports:[
//your modules here
],
providers:[
ProfileService //and other services
]
})
or in profile.service.ts
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'// which means there will be a single instance of the service in the whole application
})
export class ProfileService {
}
The navigation between the home and edit page is using Angular Router: https://angular.io/guide/router

Categories