I have an Angular 7 application, running .Net Core on the back end.
I have the following routes defined:
const routes: Routes = [
{ path: 'home', component: HomeComponent },
{ path: 'login', component: LoginComponent },
{ path: 'about', component: AboutComponent },
{ path: '**', redirectTo: 'home' }
];
In Visual Studio 2019, this is running at https://localhost:44358.
All works as expected.
But now I want to get metadata for a SAML implementation using sustainsys.saml2.aspnetcore2.
To get the metadata file, I try to enter https://localhost:44358/Saml2/ in my browser.
As expected, because the path does not match anything defined, the default route takes over and I am routed to the home page.
I removed the final path, so I no longer had any default routing for unmatched paths, and then it worked fine to get the metadata.
My question is: Is there any way to redirect to 'home' for all unmatched paths except some configured path (or paths), which would just be ignored as if the default route were not present?
Rather add a path to your base-href in index.html (e.g. <base href="/app/"/>) so that the Angular Router won't pick up paths on your root, then you'll be able to keep your wildcard redirect as is and /Saml2/ won't be intercepted.
Of course, if the app is already in production and you need to preserve URLs, you might not be in a position to make this kind of change.
Related
Here's my svelte.config.js and I'm using adapter-static :
const config = {
kit: {
adapter: adapter({
// default options are shown
pages: '../backend/build',
assets: '../backend/build',
fallback: null,
precompress: false,
}),
alias: {},
appDir: '_app',
browser: {
hydrate: true,
router: true,
},
files: {
assets: 'static',
hooks: 'src/hooks',
lib: 'src/lib',
params: 'src/params',
routes: 'src/routes',
serviceWorker: 'src/service-worker',
template: 'src/app.html',
},
floc: false,
methodOverride: {
parameter: '_method',
allowed: [],
},
paths: {
assets: '',
base: '',
},
trailingSlash: 'always',
vite: {
server: {
proxy: {
'/api': 'http://localhost:5555',
},
},
},
},
preprocess: null,};
From the backend (Go lang) I'm serving build directory & index.html file. The homepage works fine but whenever I click on any route, it sends get request to the server instead of redirecting in the app itself.
Here's the go code to serve from backend:
router := gin.Default()
router.StaticFile("/", "./build/index.html")
router.StaticFS("/_app", http.Dir("build/_app"))
I have also tried with the following code:
router.NoRoute(func(c *gin.Context) {
path := c.Request.URL.Path
c.File("./build/index.html")
})
Note: Things work fine when I run npm run preview.
The adapter-static has two distinct modes of operation: SPA and prerendering. When there are several routes, both the npm run dev and npm run preview works as intended, but once built, the static routing falls to the web server, in your case, the Go framework, but the same happens with any other static server (I have tested also Nginx and Apache).
I found a workaround to avoid converting the site to a SPA: Installing a url rewrite mechanism as a middleware in order to add the .html extension that the static server is expecting in the compiled site. In my case, I used Go Fiber github.com/gofiber/rewrite/v2 and it worked as intended (the same behavior as when using npm run dev)
For Nginx static server the solution is the same url rewrite and it could be used as explained here: https://www.codesmite.com/article/clean-url-rewrites-using-nginx
The homepage works fine but whenever I click on any route, it sends get request to the server instead of redirecting in the app itself
SvelteKit users internal router, or $app/navigator for links only if it detects a link to be the same domain as the current page. Likely your web server is misconfigured and there is a mismatch of domain somewhere in
The web browser address bar
Web server configuration
However, the question do not contain these details and is thus unanswerable "why" and how to fix it.
I'm trying to make a router for one of my components, but it is not working as expected.
Initially it was working fine, but I had to add another route to decide which mat-tab would be open when redirecting. I added the second route like that, but for some reason the third one stopped working even though the first two were working fine.
import { Routes } from '#angular/router';
import { ActionComponent } from './action.component';
import { ActionResolver } from './action.resolver';
import { ACTION_RESULT_ROUTES } from './result/action-result.routes';
export const ACTION_ROUTES: Routes = [
{ path: ':id', component: ActionComponent, resolve: { action: ActionResolver } },
{ path: ':id/:tab', component: ActionComponent, resolve: { action: ActionResolver } },
{
path: 'action-result',
children: ACTION_RESULT_ROUTES,
},
];
I got a pretty large error when trying the third route, but it starts like this:
ERROR Error: Uncaught (in promise): TypeError: You provided 'null' where a stream was expected. You can provide an Observable, Promise, ReadableStream, Array, AsyncIterable, or Iterable.
Just in case, I tried to reorder it and all three were working fine when I did it like this:
export const ACTION_ROUTES: Routes = [
{ path: ':id', component: ActionComponent, resolve: { action: ActionResolver } },
{
path: 'action-result',
children: ACTION_RESULT_ROUTES,
},
{ path: ':id/:tab', component: ActionComponent, resolve: { action: ActionResolver } },
];
Can anyone tell me why it works like that?
Edit: Added the ACTION_RESULT_ROUTES for clarification
export const ACTION_RESULT_ROUTES: Routes = [
{ path: ':id', component: ActionResultComponent, resolve: { result: ActionResultResolver } },
];
According to Angular:
"The order of routes is important because the Router uses a
first-match wins strategy when matching routes, so more specific
routes should be placed above less specific routes."
It is recommended to have static routes first, therefore your action-result path should go first, followed by the :id/:tab path then :id path last. If you have a wildcard route, it should always be the last route in your array.
The reason behind this logic is that if you had the :id path above the action-result path, angular would use the word 'action-result' as the id in the :id path.
Similarly if you had the :id path above the :id/:tab path, angular would use the words id/tab as the id in the :id path.
So, a rule of thumb is to always put your static routes first, then your dynamic routes from the most specific to the least specific followed by your wildcard route at the end.
E. G.
PATH1
PATH2
PATH3/:USER/:ROLE/:PAGE
PATH4/:SITE/:ID
PATH5:/ID
Wildcard route (*)
Im trying to redirect my page from login to another page. Im following this code.
My login component ts file:
import { Router } from '#angular/router';
constructor(private router: Router) {
}
funLogin(mobilenumber){
this.router.navigateByUrl('registration');
}
In my html Im calling this function in a submit btn,
<button class="common-btn btn" (click)="funLogin(mobileNo.value)">Submit</button>
In my app.login.routing file,
export const loginRouting: Routes = [
{
path: '', component: DashboardRootComponent, canActivateChild: [],
children: [
{ path: '', component: DashboardComponent, pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'registration', component: RegistrationComponent },
]
}
]
I have tried with "this.router.navigate" & referredlot of links. But it didnt work. Can anyone please tell me where Im going wrong or if you could give me a workingh sample it would be better.
#sasi.. try like this,
<a routerLink="/registration"><button class="btn btn-success" > Submit </button></a>
Update :
In order to use the routing in your application, you must register the components which allows the angular router to render the view.
We need register our components in App Module or any Feature Module of it (your current working module) in order to route to specific component view.
We can register components in two ways
.forRoot(appRoutes) for app level component registration like
featuteModules(ex. UserManagement) and components which you want register at root level.
.forChild(featureRoutes) for feature modules child components(Ex. UserDelete, UserUpdate).
you can register something like below,
const appRoutes: Routes = [
{ path: 'user', loadChildren: './user/user.module#UserModule' },
{ path: 'heroes', component: HeroListComponent },
];
#NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot(
appRoutes
)
],
P.S : In order to navigate from one component to another, you must include the RouterModule in corresponding Module Imports array from #angular/router package.
You can navigate one to another page in Angular in Two ways. (both are same at wrapper level but the implementation from our side bit diff so.)
routerLink directive
routerLink directive gives you absolute path match like navigateByUrl() of Router class.
<a [routerLink]=['/registration']><button class="btn btn-success" > Submit </button></a>
If you use dynamic values to generate the link, you can pass an array of path segments, followed by the params for each segment.
For instance routerLink=['/team', teamId, 'user', userName, {details: true}] means that we want to generate a link to /team/11/user/bob;details=true.
There are some useful points to be remembered when we are using routerLink.
If the first segment begins with /, the router will look up the route
from the root of the app.
If the first segment begins with ./, or doesn't begin with a slash,
the router will instead look in the children of the current activated
route.
And if the first segment begins with ../, the router will go up one
level.
for more info have look here.. routerLink
Router class
We need inject Router class into the component in order to use it's methods.
There more than two methods to navigate like navigate() , navigateByUrl(), and some other.. but we will mostly use these two.
navigate() :
Navigate based on the provided array of commands and a starting point. If no starting route is provided, the navigation is absolute.
this.route.navigate(['/team/113/user/ganesh']);
navigate() command will append the latest string is append to existing URL. We can also parse the queryParams from this method like below,
this.router.navigate(['/team/'], {
queryParams: { userId: this.userId, userName: this.userName }
});
You can get the these values with ActivatedRoute in navigated Component. you can check here more about paramMap, snapshot(no-observable alternative).
navigateByUrl()
Navigate based on the provided URL, which must be absolute.
this.route.navigateByUrl(['/team/113/user/ganesh']);
navigateByUrl() is similar to changing the location bar directly–we are providing the whole new URL.
I am using angular 7 and I solved it in this way into my project.
1.First We need to implement this Modules to our app.module.ts file
import { AppRoutingModule} from './app-routing.module';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
#NgModule({
imports: [
BrowserModule,
AppRoutingModule,
FormsModule,
],
})
2.Then Open your.component.html file and then fire a method for navigate where you want to go
<button class="btn btn-primary" (click)="gotoHome()">Home</button>
3.Then Go your.component.ts file for where you want to navigate. And add this code there.
import { Router } from '#angular/router';
export class YourComponentClassName implements OnInit {
constructor(private router: Router) {}
gotoHome(){
this.router.navigate(['/home']); // define your component where you want to go
}
}
4.And lastly want to say be careful to look after your app-routing.module.ts
where you must have that component path where you want to navigate otherwise it will give you error. For my case.
const routes: Routes = [
{ path:'', component:LoginComponent},
{ path: 'home', component:HomeComponent }, // you must add your component here
{ path: '**', component:PageNotFoundComponent }
];
Thanks I think, I share all of the case for this routing section. Happy Coding !!!
navigateByUrl expects an absolute path, so a leading / might take you to the right page
You could also use navigate and don't need the leading / but the syntax is slightly different as it expects an array for the path
https://angular.io/api/router/Router#navigateByUrl
<a class="nav-link mt-1" [routerLink]="['/login']"><i class="fa fa-sign-in"></i> Login</a>
I'm struggling a bit with react-router 2.x configuration, specifically app basename.
I've an application which may have different base root throughout its lifecycle. For instance:
/ in development
/users in production
/account in production after migration
The basename comes into play in several places:
static asset compilation in Webpack
react-router main configuration
specifying redirect routes in redux actions
providing something like redirectUrl to API calls
My current solution is to have an ENV variable and make it available both to Webpack and to the app itself by injecting window.defs via an Express server, but I still end up having things like ${defs.APP_BASENAME}/signin in way too many places throughout the app.
How can I abstract the app base, or at least tuck it away in a single location? I should be able to specify the base route in Router's config, and then simply use relative routes somehow, right? Or am I missing something?
You can decorate your history with a basename. You could mix this with a DefinePlugin in your Webpack configuration to specify which basename should be used.
// webpack.config.js
new Webpack.DefinePlugin({
BASENAME: '/users'
})
// somewhere in your application
import { useRouterHistory } from 'react-router'
import { createHistory } from 'history'
const history = useRouterHistory(createHistory)({
basename: BASENAME
})
Given the basename: /users, React Router will ignore the /users at the beginning of the pathname so:
The URL /users is internally matched by the path /
The URL /users/profile matches the path /profile.
Similarly, you do not have to append the basename to the path when you are navigating within your application.
<Link to='/friends'>Friends</Link> will navigate to /friends internally, but the URL in the location bar will be /users/friends.
Today I ran into the same issue:
On my localhost I let an NGINX serve the stuff in the root context, but on my prod server, an Apache serves the stuff from a subdirectory...
Inspired by the answer from Paul S and inspired by the infos here:
https://github.com/ReactTraining/react-router/issues/353
I got the for me working solution:
In the Webpack config file I defined a plugin for my localhost dev env:
plugins: [
new webpack.DefinePlugin({
BASENAME: JSON.stringify("/")
})
],
In the Webpack PROD config file I defined a plugin for my prod env in a subfolder, i.e. www.example.com/users:
plugins: [
new webpack.DefinePlugin({
BASENAME: JSON.stringify("/users/")
}),
And in my react-router definitions I just reference:
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import { useBasename } from 'history'
...
<Router history={useBasename(() => browserHistory)({ basename: BASENAME })}>
For me a very elegant solution and easy too. It just cost me around five hours of looking around :-)
In React Router V6.
Edit package.json and add homepage : Directory name key value as follows
"homepage" : "https://blog.sangw.in/react-student-management",
OR
"homepage" : "/react-student-management",
and on Routers BrowserRouter add basename : Directory name as follows
<BrowserRouter basename={'/react-student-management'}>
and you are done.
Visit https://blog.sangw.in/react-student-management and app will be deployed and working.
Try this it will work
import { createBrowserHistory } from 'history';
const history = createBrowserHistory({
basename: 'base-name'
})
<Router history={history}>
</Router>
I am trying to use React Router from within react.rb. I started using the reactor-router Gem, but the Gem only works with React Router < 1 and I am using React Router 2.4.0 and the API is quite different.
Over the last weeks I have taken a few approaches to getting this working but none of the approaches have been correct, each having their own fault.
Please will someone steer me in the right direction as I am all out of options.
In terms of setup, I am using Webpack to require React and React Router so the application.js which is injected by Webpack looks like this:
React = require('react')
ReactDOM = require('react-dom')
_reactRouter = require('react-router')
Approach 1 - create the Router as native JS and call ReactDOM.render to render the router when rendering a top level component
before_mount do
#admin_members = React::API::create_native_react_class(Components::Company::AdminMember)
#squad_index = React::API::create_native_react_class(Components::Squad::Index)
#squad_show = React::API::create_native_react_class(Components::Squad::Show)
#tribe_index = React::API::create_native_react_class(Components::Tribe::Index)
#tribe_show = React::API::create_native_react_class(Components::Tribe::Show)
end
and then rendering the router to a div in after_mount:
after_mount do
`ReactDOM.render(React.createElement(
_reactRouter.Router,
{ history: _reactRouter.browserHistory },
React.createElement(_reactRouter.Route, { path: "admin/members", component: #{#admin_members} }),
React.createElement(_reactRouter.Route, { path: "/squads", component: #{#squad_index} }),
React.createElement(_reactRouter.Route, { path: "/squads/:squad_id", component: #{#squad_show} }),
React.createElement(_reactRouter.Route, { path: "/tribes", component: #{#tribe_index} }),
React.createElement(_reactRouter.Route, { path: "/tribes/:tribe_id", component: #{#tribe_show} })
), document.getElementById('bh_router_div')
);`
end
This approach, although not pretty, seems to work in that the Router is created and functions as expected. A URL or /tribe/22 will load the correct TribeShow component and will pass the correct ID to the component.
The problem I have with this approach is when it comes to creating a Link as the Link component does not share the same context as the router. I believe this is down to ReactDOM.render being called once by react-rb and then once again in the code above. This creates two root components on the page (TopLevelRailsComponent) and (ReactRouter).
The Link is created thus:
class MyRouter < React::NativeLibrary
imports '_reactRouter'
end
And then used in a components render method like this:
MyRouter.Link({to: "/admin/members"}) { "and here is the link"}
The link is rendered, but clicking on it gives the following warning and does not navigate to the component:
Uncaught TypeError: Cannot read property 'push' of undefined
Looking at the properties of the Link Component I see that context is null and I believe this is why. It seems the Link is being being drawn outside the context of the router.
Approach 2 - use the react-rb API to render the router so that ReactDOM.render is not being called twice on the page
This seems to be a better approach but so far I have not managed to get this to work properly.
Building on how I create the Link above, in the render method of a component:
MyRouter.Router({history: `_reactRouter.browserHistory` },
MyRouter.Route({ path: "/admin/members", component: #admin_members})
) {}
But I get the following warning and the page does not render:
Uncaught Invariant Violation: <Route> elements are for router configuration only and should not be rendered
Approach 3 - build the Route component in native JS so that it does not get rendered:
`var AppRoutes = React.createElement(_reactRouter.Route, { path: "/admin/members", component: #{#admin_members} });`
MyRouter.Router({history: `_reactRouter.browserHistory` },
`AppRoutes`
) {}
This gets past the previous error, BUT the router does not actually route and I get the following warning (and the component does not render):
Warning: [react-router] Location "/admin/members" did not match any routes
history: As a side note, in both the examples above, I have tried to set history as such:
MyRouter.Router({history: MyRouter.browserHistroy },
`AppRoutes`
) {}
But I get a warning about providing a depreciated history and when I check the value it is null. Using _reactRouter.browserHistorygets past this warning. I am not sure if this is relevant to this fact that the router is not routing or not.
I would really appreciate any help or steer on this. Even a steer as to which of the approaches is the correct and and any hints as to how to proceed would be very welcome indeed.
This has been addressed in the V2.4.0 branch of reactrb-router https://github.com/reactrb/reactrb-router/tree/v2-4-0
Also please note the new DSL