Using react-router childRoutes - reactjs

I have a SPA which has 2 tabs in which data is rendered. The component and corresponding URL structure is as follows:
URL --> Component
/ --> PostContainer
/create --> MessageFormContainer
/update/:id --> MessageUpdatesContainer
/update/:id/infoCreate --> InfoCreateContainer
/update/:id/infoView/:id --> InfoViewContainer
If I define the routes with each having its own specific URL (sample 1), then the router works; but if use childRoutes to nest the components (sample 2), the the formed URL is displayed the URL bar, but nothing is rendered on the screen.
Sample 1:
const AppRoutes = {
path: '/',
component: MainContainer,
indexRoute: { component: PostsContainer },
childRoutes: [{
path: 'create',
component: MessageFormContainer
},{
path: 'update/:id',
component: MessageUpdatesContainer,
},{
path: 'update/:id/infoCreate',
component: InfoCreateContainer
},{
path: 'update/:id/infoView/:id',
component: InfoViewContainer
}]
}
Works.
Sample 2:
const routes = {
path: '/',
component: MainContainer,
indexRoute: { component: PostsContainer },
childRoutes: [
{ path: 'create', component: MessageFormContainer },
{
path: 'update/:id',
component: MessageUpdatesContainer,
childRoutes: [{
path: 'infoCreate',
component: InfoCreateContainer
},{
path: '/infoView/:id',
component: InfoViewContainer
}]
}]
}
]
}
Does not work. Only the URL is updated in the URL bar but nothing is rendered on the screen. The only change made to the component for Sample 2 is that they contain this.props.children tags to accommodate the childRoute components.
Any ideas would be helpful...thanks in advance!

Related

How to lazy load route with react location?

I am quite new to React, and I have a project that uses react-location
I would like to load some routes lazily only if the path is activated.
My current config is:
my base routing module
export const routes: Route[] = [
...HomeModuleRoutes, // I want this to be instantly loaded.
...LazyRoutes, // I want this to be lazy loaded.
{ path: '/', element: <Navigate to="/home" /> },
];
those 2 constants look like this :
home.routing.ts
export const routes: Route[] = [
{
path: 'home',
element: <HomeTemplate />,
children: [
{
path: '/',
element: <HomePage />,
},
],
},
];
lazy.routing.ts
export const LazyRoutes: Route[] = [
{
path: 'test',
element: <LazyTemplate />,
children: [
{
path: '/',
element: <LazyList />,
},
{
path: 'add',
element: <LazyAdd />,
},
{
path: 'detail',
element: <LazyDetail />,
},
],
},
];
I don't quite see documentation or an example on this, is it just wrapping the component with <Suspense>?
You should import your component with React.lazy like:
const HomeTemplate = React.lazy(() => import("./HomeTemplate "));
check this example for react-router v6 lazy loading

React Router v6 - how to handle nested routes but with only current page showing instead of previous pages

I am trying to understand how to handle nested routes but with different pages using react-router v6.
For instance, say the "/" path returns a list of companies. ":companyId" takes you to the company page and ":/productId" takes you to the product of that company.
What I would like to know is how to only show the content page for that product instead of showing the list of products and the list of companies too.
I think this should be nested as I need the underlying params of both company id and product id to know where I am. How do I properly use Outlet in this case?
Companies has a list of companies. Company has a list of products.
My routes currently:
const routes = [
{
path: "/",
element: <Companies />,
children: [
{
path: ":companyId",
element: <Company />,
children: [{ path: ":productId", element: <Product /> }],
},
],
},
]
const routes = [
{
path: "/",
children: [
{
index: true,
element: <Companies />,
},
{
path: ":companyId",
children: [
{ index: true, element: <Company /> },
{ path: ":productId", element: <Product /> },
],
},
],
},
];
If I understand your question/issue correctly, it seems that Companies is rendered as a layout component, in other words, it is rendered along with the nested children routes, but you want one or the other.
If you want to render one or the other then move Companies down into a child route, specifically as an index route, so it is rendered when the path is exactly "/" but not when another nested route matches.
const routes = [
{
path: "/",
children: [
{
index: true,
element: <Companies />,
},
{
path: ":companyId",
element: <Company />,
children: [
{
path: ":productId",
element: <Product />
}
],
},
],
},
]

AWS-S3 and AWS-CloudFront With React routes, multi application

I have the following scenario.
S3 bucket and several directories, one directory for each react application
All the paths of each react application start with the name of the directory hosted in the s3 bucket
For example:
S3 Directories
|--/
|--/first-app/
|--/second-app/
React routes of first-app
const routes = [
{
path: '/',
component: Empty,
exact: true,
},
{
path: '/first-app',
component: Layout,
routes: [
{ path: '/first-app/create', component: CreateCommponent},
{ path: '/first-app/login', component: Login },
{ path: '/first-app/logout', component: Logout },
],
},
]
React routes of second-app
const routes = [
{
path: '/',
component: Empty,
exact: true,
},
{
path: '/second-app',
component: Layout,
routes: [
{ path: '/second-app/create', component: OtherComponent},
{ path: '/second-app/login', component: Login },
{ path: '/second-app/logout', component: Logout },
],
},
]
How do I make cloudFront serve each application in each directory independently but under the same domain?
https://my.domain.com/first-app >> serve react application middle index.html of first-app
https://my.domain.com/second-app>> serve react application middle index.html of second-app
You can do this using Lambda#Edge in order to manipulate the request parameters before sending the request to the bucket. here is a similar example: here

Ionic - Navigate to a Ionic Tabs page with a specific Id Error: Cannot match any routes. URL Segment:

I'm working on an app that has the following use case which I'm not sure how to implement.
I'm on a page that display a list of Game/Match Results. When I click on that particular Game I want to be brought to a more detailed page for that Game, however this Detailed page is a tabs page (has 2 tabs on it).
Here's the code in my List of Games page:
<ion-card *ngFor="let match of matches; let i = index" tappable routerLink="/../match-details/match-details-info/{{match.id}}"
Once I click on that ion-card I want to be brought to a page that has tabs - I imagine the URL should look something like /match-details/match-details-info/XYZ1234345 but I'm not sure how to get there.
Here is my match-details-routing.module.ts:
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { MatchDetailsPage } from './match-details.page';
const routes: Routes = [
{
path: '',
component: MatchDetailsPage,
children: [
{
path: 'match-details-info/:id',
children: [
{
path: '',
loadChildren: '../match-details-info/match-details-info.module#MatchDetailsInfoPageModule'
}
]
},
{
path: 'match-details-lineup/:id',
children: [
{
path: '',
loadChildren: '../match-details-lineup/match-details-lineup.module#MatchDetailsLineupPageModule'
}
]
},
{
path: 'match-details-scorers/:id',
children: [
{
path: '',
loadChildren: '../match-details-scorers/match-details-scorers.module#MatchDetailsScorersPageModule'
}
]
},
{
path: '',
redirectTo: '/match-details/match-details-info',
pathMatch: 'full'
}
]
},
{
path: '',
redirectTo: '/match-details/match-details-info',
pathMatch: 'full'
}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class MatchDetailsPageRoutingModule {}
Here is the error I'm seeing
Error: Cannot match any routes. URL Segment: 'match-details/match-details-info/inhOKexG3AtcJNnj0xyW'
Error: Cannot match any routes. URL Segment: 'match-details/match-details-info/inhOKexG3AtcJNnj0xyW'
The url looks correct to me but for some reason it can not match the route.
Also including part of the app-routing.module.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { AuthGuard } from './services/user/auth.guard';
const routes: Routes = [
{ path: '', loadChildren: './tabs/tabs.module#TabsPageModule' },
{ path: 'match-details/:id', loadChildren: './pages/match-details/match-details.module#MatchDetailsPageModule' },
{ path: 'player-details/:id', loadChildren: './pages/player-details/player-details.module#PlayerDetailsPageModule' },
{ path: 'login', loadChildren: './pages/login/login.module#LoginPageModule' },
//{ path: 'admin-home-tabs, loadChildren: './pages/admin-home-tabs/admin-home-tabs.module#AdminHomeTabsPageModule' },
{ path: 'reset-password', loadChildren: './pages/reset-password/reset-password.module#ResetPasswordPageModule' },
On your routes you can include the /:id in the path of the match-details-info page as below, this will indicate that the page accepts an id parameter
const routes: Routes = [
{
path: '',
component: MatchDetailsPage,
children: [
{
path: 'match-details-info/:id',
children: [
{
path: '',
loadChildren: '../match-details-info/match-details-info.module#MatchDetailsInfoPageModule'
}
]
},
{
path: 'match-details-lineup',
children: [
{
path: '',
loadChildren: '../match-details-lineup/match-details-lineup.module#MatchDetailsLineupPageModule'
}
]
},
{
path: 'match-details-scorers',
children: [
{
path: '',
loadChildren: '../match-details-scorers/match-details-scorers.module#MatchDetailsScorersPageModule'
}
]
},
{
path: '',
redirectTo: '/match-details/match-details-info',
pathMatch: 'full'
}
]
},
{
path: '',
redirectTo: '/match-details/match-details-info',
pathMatch: 'full'
}
];
The routerLink on your ion-card should then include the match-details-info path to navigate directly to the tab, you should then also move the code to get the id from to the match-details-info page
<ion-card *ngFor="let match of matches; let i = index" tappable routerLink="/../match-details/match-details-info/{{match.id}}"

how to redirect to parent route from children route in angular 2

I created child router in my router configuration and configured my child router in way that it redirects to parent router component. But the configuration doesn't work as expected. Instead it redirects to error page as it didn't find the configured path.
My app.route.ts file
import { ModuleWithProviders } from '#angular/core';
import { CanActivate, Routes, RouterModule } from '#angular/router';
// Component
import { HomeRouterComponent } from '../../modules/home/homerouter.component';
import { ChannelComponent } from '../../modules/channels/channel.component';
import { ErrorComponent } from '../../modules/errorPage/error.component';
const appRoutes: Routes = [
{
path: 'home',
component: HomeRouterComponent,
canActivate: [LoginCheck]
},
{
path: '',
redirectTo: 'home',
pathMatch: 'full',
},
{
path: 'channel',
component: ChannelComponent,
children: [
{
path: '',
redirectTo: 'channel',
pathMatch: 'full',
}
]
},
{
path: '**',
component: ErrorComponent
}
];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
May I ask why you have a child route without a path? But since it's not an actual path, you wouldn't need to redirect anywhere, since there is no change in url. I had a similar setup where I did not want to show a child initially upon navigation. Leaving it empty worked fine for me, so try:
{
path: 'channel',
component: ChannelComponent,
children: [
{
path: '',
}
]
}

Resources