I have a scenario where the first segment in the url will be a unique identifier. That unique identifier will be used in main routes and in the child routes as well.
Here is how i have defined my routes config
export const routes:RouterConfig = [{
path: ':academy_url',
children: [
{path: '', component: CoursesComponent},
{path: 'courses',
children: [
{path: '', component: CoursesComponent}
]
}
}
];
:academy_url is the param i plan on using in the child components. I can access this param in the child components (CoursesComponent for example), but i do not have for some reason access to it in the main app component.
The params array is empty in the main component when i try observables as well as snapshot.How do i access this param in app component? Right now i have a workaround which depends on a service emitting the param value from child components, but that is very inconvenient as this happens every time a component loads or page refreshed.
I need a more direct approach and i feel that it's either a bug or maybe the main app component is not supposed to have access to entry level params?
Also, i tried to create a plunker but i'm not sure how i make it work in there as it gives me undefined route error for it's plunker url key.
Related
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
I'm working on a web application using Vue 2 as the framework and the accompanying Vue Router for routing purposes.
I'm developing a kind of tabbed view, so my current approach is to define child routes for my main component. Something along the lines of:
{ path: '/user/:id', component: User, children: [
{ path: '', component: UserHome },
{ path: 'profile', component: UserProfile },
{ path: 'posts', component: UserPosts }
]}
The setup is OK and routing works as expected. I'm now looking into defining links from the User component's template to its children (the tabbed navigation). I'm also looking to define a link from the UserHome component directly to its sibling components (UserProfile& UserDetails).
As far as I can tell there's no easy way to avoid repeating the full path in the toattribute of the router-link component to avoid breaking the navigation, see this working Fiddle & this broken Fiddle and notice the values of the to attributes. I would expect to be able to define a relative path as the value of the to attribute to navigate between child and/or sibling paths.
Does anyone know if there's a better way to avoid repeating full navigation paths in a router-link 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 !
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 }
]
},
]
});
I'm confused about how and when you can use getChildRoutes because it's part of PlainRoute. How do you access PlainRoute in the first place? So instead of building <Route> components I can use <PlainRoute>s and then inside the component it was rendering it will have getChildRoutes? What does partialNextState refer to?
Plain routes are ordinary JavaScript objects, and can be used in <Router> like so:
const routes = {
path: '/',
component: App,
indexRoute: {
component: Home,
},
childRoutes: [
{ path: 'page1', component: Page1 },
{
path: 'page2',
component: SomeWrapper,
childRoutes: [
{ path: 'subpage1', component: Subpage1 },
],
},
],
};
ReactDOM.render(<Router history={ browserHistory } routes={ routes }/>, document.body);
That is, the indexRoute - if present - corresponds to adding an <IndexRoute> as a child of a <Route>, and childRoutes corresponds to adding child <Route>s. They both accept the same attributes as the corresponding JSX tags accept props.
Plain routes are useful for example for splitting your route definition up in multiple files. In a large app, it may be useful to decouple pages from their exact location in the route hierarchy, and build the route hierarchy up by importing childRoutes to immediate parent modules instead of having the entire route hierarchy hardcoded into the root module. It is also easy to build reusable navigation components like tab containers and breadcrumbs if you use plain routes, as the routes themselves can then be sent as props defining the links those components should include.
getChildRoutes and getIndexRoute are asynchronous variants of the childRoutes and indexRoute attributes, and allow for dynamic routing and code splitting. For example, you could for fun make getChildRoutes refer to itself recursively. I don't know what partialNextState is supposed to be, and I've never needed to use it.