Angular 7 children component route without parent route - javascript

I have a problem with routes in my Angular 7 application. I have a page frame, where I would like to switch to different components according to route without refreshing / changing main page frame.
In my page frame I have <router-outlet>.
My main route is http://localhost:4200/login.
When I go to this page, I would like to show component which is related to this route.
My second route which I would like to show is http://localhost:4200/forgot-password.
I would like to see on exactly the same page second component which is related to forgot password form.
I tried to achieve this with children and it works, but when I make a redirection it adds /forgot-password at the end of existing http://localhost:4200/login url. In this case I've always receive http://localhost:4200/login/forgot-password in url. What I'm trying to achieve is to show in url http://localhost:4200/forgot-password, without /login.
app.routes.ts
// Login Page
{
path: 'login',
component: LoginComponent,
canActivate: [ HTTPSGuard ],
children: [
{
path:'',
component: Login2ComponentComponent,
data: {
animation: 'Sign-In'
}
},
{
path: 'forgot-password',
component: ForgotPassword2Component,
data: {
animation: 'Forgot-Password'
}
}
]
}
In my login component I have a link:
<a [routerLink]="['/forgot-password']">Go to forgot</a>
But it adds me to the current /login route /forgot-password.
Maybe there is a router attribute which I can use in app.routes.ts to make this happened?
Thank you for help!

Related

Angular component reloads when navigating

Routes for my Module:
const routes: Routes = [
{ path: ":level1/:level2/:level3", component: CategoriesComponent },
{ path: ":level1/:level2", component: CategoriesComponent},
{ path: ":level1", component: CategoriesComponent},
{ path: "", component: CategoriesComponent },
];
the Categories component Generates some links like so:
<a [routerLink]="['category1']" [relativeTo]="activatedRoute">My Link</a>
the ngOnInit & ngOnDestroy are called each time it navigates between those routes.
What I need is the component to stay mounted and not re-init each time.
Stackblitz link to illustrate the difference between using QueryParameters and RouteParameters: Angular example
NOTE: Dont suggest RouteReuseStrategy: that isn't the answer we are looking for. I have another angular application that doesn't reload the component between routes. And this is the official expected behaviour.
You need to dive into a RouteReuseStrategy and create your custom strategy with saving touched pages
Docs
RouteReuseStrategy allows you to tell Angular not to destroy a component, but in fact to save it for re-rendering at a later date. https://stackoverflow.com/a/41515648/15439733

Angular routing bug - this.router.navigateByUrl() and this.router.navigate()

I am creating angular application that will handle documentation for my GitHub apps, in more complex way than just readme files. I want to redirect user after clicking in topnav dropdown to selected route, but there's problem with router. (I need to redirect with some parameters, but it doesn't work even with simple path reditect). Those methods redirect to target route for like 1 seconds (like excepted), then user got redirected back to root page.
Code:
/* First element is project name, second is category/part of application name */
choices = ["typing_speed_test", "overview"]
json = json
constructor(private router: Router){}
onProjectClick($event){
this.choices[0] = $event.target.innerHTML.trim();
this.choices[1] = "overview";
this.redirect();
}
onCategoryClick($event){
this.choices[1] = $event.target.innerHTML.trim();
this.redirect();
}
redirect(){
this.router.navigateByUrl("404");
}
Routes:
const routes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'project/:project_name/:category', component: SubpageComponent },
{ path: '404', component: NotFoundComponent },
//{ path: '**', redirectTo: '404', pathMatch: 'full' }
];
Link to gif with problem: https://imgur.com/a/x2mPxvh
Full code in github repo: https://github.com/Dolidodzik/DocsForMyApps (if you used code from here to answer this question, please point that in your answer)
I think I may did some stupid mistake, because I am pretty new in Angular, but I couldn't do it, because every google question showed me solves for ERRORS, when redirect doesn't work at all, not to bugs like in my situation.
You need to remove the href="#" from your anchor links in your navigation bar. It's causing the browser to reload:
<a class="dropdown-item" *ngFor="let item of categories() | keyvalue">
{{item.key}}
</a>
Also this is a bit weird solution:
this.choices[0] = $event.target.innerHTML.trim();
You better just send the item variable in your function call in your template, and you can then read this in your component event handler:
onProjectClick(item){
this.choices[0] = item.key;
this.choices[1] = "overview";
this.redirect();
}
the problem is your lins look like this:
link
default link behavior causes your app reload from the start. you should use [routerLink]="['someUrl']" instead of href. If you need that href in some cases, consider calling $event.preventDefault() to cancel the native browser navigation

In Angular 8 Router parent route remains the same when navigating to the route with other parent

I'm working on a project written on Angular (v8.2.8) and use router with the same version. The architecture of the routing is the following:
I have app-routing.module.ts where I have 3 entries for routes array:
Shell.childRoutes([...array of routes]),
Case.childRoutes([...array of routes]),
{ path: '**', redirectTo: '/', pathMatch: 'full' }
Shell - that is parent component for app internal pages.
Case - that is parent component for app public pages.
Method child routes do almost the same for both components:
export class Shell {
static childRoutes(routes: Routes): Route {
return {
path: 'app',
component: ShellComponent,
children: routes,
canActivate: [AuthenticationGuard],
data: { reuse: true }
};
}
}
and
export class Case {
static childRoutes(routes: Routes): Route {
return {
path: '',
component: CaseComponent,
children: routes,
data: { reuse: true }
};
}
}
App have dashboard component for Shell parent and home component for Case parent.
User loads the page at home route and markup is the following:
<app-root>
<app-case>
<router-outlet></router-outlet>
<app-home></app-home>
</app-case>
</app-root>
And after redirect to the dashboard route I expect to have the following markup:
<app-root>
<app-shell>
<router-outlet></router-outlet>
<app-dashboard></app-dashboard>
</app-shell>
</app-root>
But I receive
<app-root>
<app-case>
<router-outlet></router-outlet>
<app-dashboard></app-dashboard>
</app-case>
</app-root>
So the exact issue is in test case:
User is on a route which exist in Shell parent.
Then if user will be redirected to any route in Case parent - the parent will stays the Shell. And the same situation works in other direction. If Case route was load first, after redirect to Shell route parent will stay the case.
I tried to edit different parameters in the childRoutes method, but no success, I just don't understand is it the issue in the engine, or I just need to specify some additional parameters.
Basically I resolved this issue. For those who had the same issue - for me issue was in custom route reusable strategy which was implemented. When I was switching from Case to Shell route-reusable-strategy function shouldReuseRoute returned true, so route was reused.

Angular 2 routes resolve different component

Here is my use case:
When i load url /product/123 i want to load component ProductComponent
This is my setup:
RouterModule.forRoot([
{
path: 'product/:productId',
component: ProductComponent
},
{
path: '**', component: NotFoundComponent
},
]),
Now I have added a resolver to check if that product id exists, so my setup looks like this:
RouterModule.forRoot([
{
path: 'product/:productId',
component: ProductComponent,
resolver: {
productResolver: ProductResolver
}
},
{
path: '**', component: NotFoundComponent
},
]),
My resolver checks if that productId parameter exists via api call. The problem i have is that when productId is not found I want to load NotFoundComponent rather than redirecting to different page (i dont want to change url like angular 2 documentation suggests).
Anyone knows how to do that? if not productId found via resolver load NotFoundComponent without changing url/navigate?
I think all you want to do is skip the location change when you navigate to your NotFoundComponent. I'm assuming you've injected the Router into your resolver and are doing something like this when the ID does not exist:
router.navigate(['someUrl']);
Or you might be using the navigateByUrl method. Either way, you can tell the router not to change the URL:
router.navigate(['someUrl'], {skipLocationChange: true});
Don't see why you'd need to load your component via router settings, I'd put it inside the Component that tries to fetch it from the service, and then if it doesn't get a result back toggle some boolean that controls whether the NotFoundComponent gets shown. Some pseudo-ish code below:
ngOnInit(){
if (this.route.snapshot.params && this.route.snapshot.params['id']){
myService.getTheThingById((success)=>{
this.isFound = true;
},(err)=> {
this.isFound = false;
});
}
Then assuming your NotFoundComponent has a selector in it like 'not-found-component' throw it in the template for the component that's calling the service.
<not-found-component *ngIf='!isFound'></not-found-component>
I once faced this problem.
What I did was, in the component, to create 2 other components (in your case, you have ProductComponent, NotFoundComponent, and the other one you want to navigate to, let's say ArticleComponent)
Then I inserted 2 of the components in the main one :
product.component.html
<app-notFound></app-notFound>
<app-article></app-article>
After that, in your ngOnInit, you see if the parameter is there. If he is, then you log it in a property, let's say isParam = true.
Your template becomes
<app-notFound *ngIf="!isParam"></app-notFound>
<app-article *ngIf="isParam"></app-article>
It may not be the best solution out there, but it worked for me !

How can I get vue-router data into the parent template?

I have 2 route components:
1) A people product list component 2) A product detail component
The list shows the products and then there is a router-link to that product using history in the router definition/scope.
What I am trying to achieve is to get the data from the parent list routes into the child detail product template.
So I am working with vuex as I am storing the data in the store method. Below is the gist example with the setup I have got.
https://gist.github.com/mdunbavan/5cb756ff60e5c5efd4e5cd332dcffc04
The PeopleListing component works well and when clicking the router link it goes to the correct url and the data in the vue debug looks okay for vuex as below:
state:Object
currentProduct:undefined
products:Array[0]
route:Object
from:Object
fullPath:"/products/copy-of-long-shirt-dress-tudor"
hash:""
meta:Object (empty)
name:"product"
params:Object
path:"/products/copy-of-long-shirt-dress-tudor"
query:Object (empty)
What I am trying to do is basically render the data so it shows the router data within the homepage still and not look like it is going to another page which is what it is doing at the moment. The journey I am looking to create is as follows:
1) index page renders the PeopleListing
2) when clicking the it opens some animation within that template
3) the animation then renders the data from that clicked route such as '/products/the-product-title'
On point 3) we have to try and get all data attributes from that object.
Is it possible with the setup that I have got in my gist?
Thanks in advance!!
'product/:handle' is a child route for the '/' route, as you want to nest them.
Your router should look like this.
As you want to pass data to your route using params.
When props is set to true, the route.params will be set as the component props.
const router = new VueRouter({
mode: 'history',
routes: [
{ path: '/', component: PeopleListing,
children: [
{ name: 'product', path: '/products/:handle', component: ProductDetail, props: true }
]
},
]
});

Categories

Resources