React implement routes from array programitically - reactjs

I have a file called routes.js there I import components and create a routes array.
routes.js
import Country from '../src/components/country/Country';
import Countries from '../src/components/country/CountriesList';
import User from '../src/components/user/User';
import UsersList from '../src/components/user/UsersList';
export const routes = [
{
name: 'USER',
children: [
{
name: 'Create',
path: '/user-create',
component: User,
// isHidden: true,
},
{
name: 'Update',
path: '/update-user',
isHidden: true,
component: User,
},
{
name: 'View',
path: '/users',
component: UsersList,
// isHidden: true,
},
],
},
{
name: 'COUNTRY',
children: [
{
name: 'Create',
path: '/country',
component: Country,
},
{
name: 'View',
path: '/countries',
component: Countries,
},
],
},
],
},
];
Then, I want to import that routes array and render routes programmatically.
I did this.
{routes.map(
{children}=>
children.forEach({component,path} => <Route component={component} exact path={path}/>)
)}
This gives me a syntax error.
I think this is because I am trying to render with a ForEach loop.
How do I fix this syntax problem?

You can use the Array#flatMap and Array#map function which will return an array of components which React can render.
{routes.flatMap(items => items.children).map(({ component, path }) => <Route component={component} exact path={path}/>)}
You were also missing some parens () around the curly braces which caused the Syntax error.
E.g. in the following part, you are trying to destructure the object containing the children property. However, you will need to wrap the destructing syntax with parens if you use this in an arrow functions.
{routes.map({children} =>

Related

Component not rerendering post updation of redux react-router-dom v6 [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 days ago.
Improve this question
Steps - When I change the url path. My url is having nested routes. The component is successfully re-rendering if my url path does not change. When I change my Url path i.e from http://localhost:3000/1/1/library/data to http://localhost:3000/1/1/library/model I don't get the fresh value of redux.
If you guys can check if there any issue with the code why PrivateLayout is not re-rendering post update of redux?
// Route Setting
const Routing = () => {
return (
<Routes>
<Route element={<PrivateLayout />}>
<Route path=':subscriptionId/:packId'>
{privateRoutes.map(renderRoute)}
</Route>
<Route path='/' element={<ScopeSelection />} />
<Route path='*' element={<ScopeSelection />} />
</Route>
</Routes>
);
};
const renderRoute = ({ path, subRoutes, element: Element, hasChildren }) => {
if (!path) return null;
if (subRoutes) {
return subRoutes.map(subRoute =>
renderRoute({ ...subRoute, path: `${path}/${subRoute.path}` })
);
}
if (hasChildren) path += '/*';
return <Route key={path} path={path} element={<Element />} />;
};
const privateRoutes = [
{
name: 'Dashboard',
path: 'dashboard',
icon: DashboardIcon,
subRoutes: [
{
name: 'AI Performance',
path: 'ai-performance',
icon: DashboardIcon,
iconActive: DashboardIcon,
element: AIPerformance,
hasChildren: true,
defaultParams: `${MONITORING}/${UNIT_WAFER}`
}
]
},
{
name: 'Library',
path: 'library',
icon: LibraryIcon,
subRoutes: [
{
name: 'Data Library',
path: 'data',
icon: DataLibIcon,
iconActive: DataLibIconActive,
element: DataLibrary,
hasChildren: true
},
{
name: 'Model Library',
path: 'model',
icon: ModelLibIcon,
iconActive: ModelLibIconActive,
element: ModelLibrary,
hasChildren: true
},
{
name: 'Defect Library',
path: 'defect',
icon: DefectLibIcon,
iconActive: DefectLibIconActive,
element: DefectLibrary
},
{
name: 'Use Case Library',
path: 'usecase',
icon: DefectLibIcon,
iconActive: DefectLibIconActive,
element: UseCaseLibrary
}
]
},
{
name: 'Configuration',
path: `configuration`,
icon: ConfigurationIcon,
element: Configurations,
hasChildren: true,
defaultParams: SYSTEM_CONFIG
},
{
name: 'Notifications',
path: `notifications`,
icon: NotificationsIcon,
element: Notifications
},
{ name: 'Review', path: 'annotation/:annotationType', element: Reviewdata },
{ name: 'Waferbook', path: 'dashboard/wafer-book', element: WaferBook },
{
name: 'Model Library Train Model',
path: 'library/model/train',
element: TrainModel
},
{
name: 'Model Library Re-train Model',
path: 'library/model/retrain/:modelId',
element: RetrainModel
},
{
name: 'Model Library Performance',
path: 'library/model/model-performance',
element: ModelPerformance
}
];
// Here is my private layout
const PrivateLayout = () => {
const accessToken = useSelector(({ user }) => user.accessToken);
/// Here is the issue isStatusWidgetOpen is not re-rendering though my redux has been updated successfully seen via redux chrome extension
const isStatusWidgetOpen = useSelector(
({ statusWidget }) => statusWidget.isWidgetOpen
);
console.log('isStatusWidgetOpen:::', isStatusWidgetOpen);
useEffect(() => {
if (!accessToken) {
refreshToken().then(setSessionLogger);
}
}, []);
return (
<WithCondition
when={accessToken}
then={
<AppLayout>
<Outlet />
</AppLayout>
}
or={<Spinner />}
/>
);
};
package.json
"react-router-dom": "^6.4.5",
"react-redux": "^8.0.4",
"redux-thunk": "^2.4.2",
"react": "^18.2.0",

Cant use React Icons component as an object value typescript

I am developing a personal website using typescript and react, and for my footer, I am mapping through an array of objects which each have a url property, as well as an icon property. The Icon property is supposed to have multiple different React Icons as the value, so that through each iteration, I can display a different Icon. When I originally implemented this in javascript, my code worked just fine, but after switching my codebase over to typescript, I am presented with this error:
"Parsing error: '>' expected.eslint
'FaGithub' refers to a value, but is being used as a type here. Did you mean 'typeof FaGithub'?ts(2749)"
This is the typescript implementation that I have so far. I have tried removing the angled brackets, and that eliminates the error, but I am unable to actually display the icon when mapping through the array. I would really appreciate any advice.
const socialIcons: { icon: IconType, url: string }[] = [
{
icon: <FaGithub />,
url: "./"
},
{
icon: <FaLinkedin />,
url: "./"
},
{
icon: <FaTwitter />,
url: "./"
},
{
icon: <FaInstagram />,
url: "./"
},
{
icon: <FaFacebook />,
url: "./"
},
]
{socialIcons.map((icons, index) => {
const {icon, url} = icons;
return (
<a href={url} key={index} target="_blank" rel="noopener noreferrer">
{icon}
</a>
);
})}
This is how the socialIcons array originally looked in regular javascript.
const socialIcons = [
{
icon: <FaGithub />,
url: "./"
},
{
icon: <FaLinkedin />,
url: "./"
},
{
icon: <FaTwitter />,
url: "./"
},
{
icon: <FaInstagram />,
url: "./"
},
{
icon: <FaFacebook />,
url: "./"
},
]
I figured out a solution, all I needed to do was change the file extension from .ts to .tsx, and make the type of the value a JSX.Element to input react components as values within objects without a typescript compiler error.
I had difficulties to type icons myself. I found this solution to be working.
export interface IRoute {
path: string;
name: string;
icon: ReactNode;
layout: string;
}
export const routes: IRoute[] = [
{
path: "/dashboard",
name: "Dashboard",
icon: <FiHome />,
layout: ""
},
{...}
]

How do I render this object in React with React Router?

How do I render this object using react router? I want to render this object in a menu.
{main: 'Main', about: 'About', contacts: 'Contacts', '404': 404}
Refactor it this way:
const menu = [
{ title: 'Main', path: '/main' },
{ title: 'About', path: '/about' },
{ title: 'Contacts', path: '/contacts' },
{ title: '404', path: '/404' }
];
Now do this in your JSX wherever you want your menu:
{menu.map(item => <Link to={item.path} alt={item.title} />)}
Don't forget to import Link:
import { Link } from 'react-router-dom'

Angular 2 routing issue

Can somebody help me with angular 2 routing.
I have 2 pages.. home and search results page..
Header for home and search results page are different..
here is my code, I am able to display the home page with header but when I go to search results page, header is not getting replaced with new one..
home.routes
export const HomeRoutes: Routes = [
{ path: '', component: HomeComponent},
{ path: '', component: HomeHeadbarComponent, outlet: 'route1' }
];
search.routes
export const SearchRoutes: Routes = [
{ path: 'search', component: SearchPanelComponent},
{ path: 'search', component: HeadbarComponent, outlet: 'route1' }
];
App.html
<router-outlet name="route1"></router-outlet>
<router-outlet></router-outlet>
Appreciate your help
Your home.routes should be below code this will be redirect to you HomeComponent and if you want to redirect it on SearchPanelComponent both you can use in below code
import { Routes, RouterModule } from '#angular/router';
import { HomeComponent} from './Home';
export const routes: Routes = [
{ path: '', redirectTo: 'Home', pathMatch: 'full' },
{ path: 'Home', component: HomeComponent},
{ path: 'search', component: SearchPanelComponent},
];
export const appRoutingProviders: any[] = [
];
export const routing = RouterModule.forRoot(routes);
I assume, that happens because you have empty path path: '' for the first header, so it could overlap the new one. Could you try with the different path, and check it out, should help.
got it working with the code below..
{
path: 'search',
children: [
{
path: '',
component: SearchPanelComponent
},
{
path: '',
component: HeadbarComponent,
outlet: 'route1'
}]
}

RC5 Angular2 route default component

I have existing PHP website, which I start adding angular2 component to.
I have added router script, to help load different component by its url.
When I navigate away from the component page, I get following error Error: Uncaught (in promise): Error: Cannot match any routes: 'dashboard'
I understand, that I need to create another component to make this error disappear. But I don't want to create another component, because there are so many pages, I would end up creating component for each page.
So I wanted to ask, how to make 1 default component, which will pickup if no component was available OR how can I just make this error disappear, so it does not trigger if it cant found any router or component for that path.
import { ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import {TestComponent} from "./test/test.component";
const appRoutes: Routes = [
{ path: 'search', component: TestComponent }
];
export const appRoutingProviders: any[] = [
];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
you may add a wildcard route which will redirect to a default component if route does not match.
{ path: 'default', component: DefaultComponent },
{ path: '**', redirectTo: '/default' }
So if the route does not match your default component will be loaded in the router outlet.
Hope this helps!!
I use this as default route:
{ path: '', component: Home, text: 'Home' }
and this is my full routes:
export const routes: TextRoute[] = [
{ path: '', component: Home, text: 'Home' },
{ path: 'accordion', component: AccordionDemo, text: 'Accordion' },
{ path: 'alert', component: AlertDemo, text: 'Alert' },
{ path: 'buttons', component: ButtonsDemo, text: 'Buttons' },
{ path: 'carousel', component: CarouselDemo, text: 'Carousel' },
{ path: 'collapse', component: CollapseDemo, text: 'Collapse' },
{ path: 'dropdown', component: DropdownDemo, text: 'Dropdown' },
{ path: 'pagination', component: PaginationDemo, text: 'Pagination' },
{ path: 'popover', component: PopoverDemo, text: 'Popover' },
{ path: 'progressbar', component: ProgressbarDemo, text: 'Progressbar' },
{ path: 'rating', component: RatingDemo, text: 'Rating' }
];
export const AppRoutes = RouterModule.forRoot(routes, { useHash: true });
Check out my learning angular2 project at github, stars are welcome.
Im too new to comment, my question is if you are using express backend? app.use() might be able to save you some trouble. instead of declaring the routes try in app.js
var routes = require('routes');
app.use('/name-of-url', routes )
then in routes
router.get('name-of-url', function(res,req,next){
res.sendFile(path to php file to serve)
})
You may also need to change your express templating engine to php, not entirely sure.

Resources