Angular load url when using a router - javascript

Im using Angular 7 + router. For example, my home page is localhost:4200, one of my router's url is localhost:4200/route and I have an API end point at localhost:4200/api/foo.
I'm trying to let the browser load the api end point from both locations. If I put an anchor with href pointing to the API end point, both anchor link works perfectly. However, I need to do it programmatically and I have tried all of the following methods
window.open("localhost:4200/api/foo","_self")
window.location.replace('localhost:4200/api/foo');
window.location.href = 'localhost:4200/api/foo';
They all works on the home page but if I'm in the router page, doing so will get me to the home page.
Any help is greatly appreciated!
To be specific, I have a spring boot server with url patterns like /api/*. All other urls are handled by angular. I want the browser to load localhost:4200/api/foo, which is directly handled by a get request defined in the server
Demo:
My nav bar is a component and it stays the same regardless of the router.
The code behind that button click is below. Note that the first time I click it under some Angular routed url, it loads the home page, not google.com
onLogIn() {
window.open('https://www.google.com',"_self");
}
Routing.ts file
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { IndexComponent } from "./index/index.component";
import { MicroserviceComponent } from "./microservice/microservice.component";
const routes: Routes = [
{ path: '', component: IndexComponent},
{ path: 'microservice/:id', component: MicroserviceComponent}
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }

add pathMatch to your empty route, it's missing tht's why you're redirected to the home component
const routes: Routes = [
{ path: '', component: IndexComponent, pathMatch:'full'},
{ path: 'microservice/:id', component: MicroserviceComponent}
];

Related

Challenges with auxiliary routers in Angular 7

Part of my Angular app requires two components to be shown at the same time, other parts of my app only require a single component to be shown. I'm having no issues with routing related to the 'pages' that only have single components on them, but I am having some challenges with the one where I'm taking advantage of the auxiliary router. Code with comments is included below. Basically getting a route not found error when I'm trying to get 'back' from the view that uses the aux router.
//Relevant import to support routing in app.module
import {
Routes,
RouterModule
} from '#angular/router';
//Route array in app.module
const appRoutes: Routes = [{
path: '',
component: HomeComponent
},
{
path: 'admin',
component: BuilderComponent
},
{
path: 'sandbox',
component: SandboxComponent
},
{
path: 'adventure',
component: GuideComponent
},
{
path: 'scanner',
component: ScannerComponent,
outlet: 'secondary'
}
];
//relvant import in imports array in app.module
RouterModule.forRoot(appRoutes)
//Content of my app.component.html file
<
div class = "container" >
<
app - header > < /app-header> <
router - outlet > < /router-outlet> <
router - outlet name = "secondary" > < /router-outlet> < /
div >
//Code in one of my components HTML file that is attached to a button and successfully calls the page with two components
[routerLink] = "[ {
outlets: {
primary: 'adventure',
secondary: 'scanner'
}
}
]
"
//Code I'm trying to use in the 'multi component' view that tries to get back to the 'home' page
[routerLink] = "[ {
outlets: {
primary: '',
secondary: 'sandbox' //This is a blank HTML component so that it doesn't screw up the look of components that don't need the aux router. Super hacky and am welcome to suggestions on how to fix this as well.
}
}
]
"

Navigating to the current route in Angular 2?

I am trying to reload the current page in Angular.
So when I reload the page, my root component is called and this line is executed:
console.log(this.router.routerState.snapshot.url)
which prints "/component-x"
and then I execute this line of code:
this.router.navigate(['/component-x]')
And it does not work and I am logged out of my application.
Is navigating to the current route in Angular supported?
And how else can I achieve reloading the current page?
Note my application is being hosted on Cloudfront on AWS, and I have rule set up that returns index.html when there is 404 error (i.e. when a page refresh occurs), and I have followed this guide around reloading the current route in Angular: https://medium.com/engineering-on-the-incline/reloading-current-route-on-click-angular-5-1a1bfc740ab2
But it is still not working. Can somebody please point out what I am missing?
Thanks!
You can use the onSameUrlNavigation from Angular router:
#ngModule({
imports: [RouterModule.forRoot(routes, {onSameUrlNavigation: ‘reload’})],
exports: [RouterModule],
})
And then use the runGuardsAndResolvers on your route and set it to always:
export const routes: Routes = [
{
path: 'my-path',
component: MyComponent,
children: [
{
path: '',
loadChildren: './pages/my-path/mycomponent.module#MyComponentModule',
},
],
canActivate: [AuthenticationGuard],
runGuardsAndResolvers: 'always',
}
]
With these two changes your router is configured. Now you need to hook into NavigationEnd in your component:
export class MyComponent implements OnInit, OnDestroy{
// ... your class variables here
navigationSubscription;
constructor(
// … your declarations here
private router: Router,
) {
// subscribe to the router events - storing the subscription so
// we can unsubscribe later.
this.navigationSubscription = this.router.events.subscribe((e: any) => {
// If it is a NavigationEnd event re-initalise the component
if (e instanceof NavigationEnd) {
this.initialiseMyComponent();
}
});
}
initialiseMyComponent() {
// Set default values and re-fetch any data you need.
}
ngOnDestroy() {
// avoid memory leaks here by cleaning up after ourselves. If we
// don't then we will continue to run our initialiseInvites()
// method on every navigationEnd event.
if (this.navigationSubscription) {
this.navigationSubscription.unsubscribe();
}
}
}
And there you go, you have reload ability now. Hope this helps. Unfortunately docs are not very clear on these.

page url get write when push page on ionic2

all I'm new on ionic2 and angular2 I want to ask if this method true or not?
I had an array that contains some menu with page property example like this
{
"menu" : [
{"nama" : "My Repair Request","page":"RepairRequestPage","icon":"ios-hammer-outline"},
{"nama" : "My Front Desk Instruction","page":"FrontDeskinstPage","icon":"ios-desktop-outline"},
{"nama" : "Amenity Reservation","page":"","icon":"ios-clipboard-outline"},
{"nama" : "My Delivery","page":"","icon":"ios-cube-outline"}
]
}
and then i loop to view and give some function :
<div>
<ion-card class="menuCard center_content" *ngFor="let item of list_menu" (click) = 'openMenu(item)'>
<ion-icon ios="{{item.icon}}" md="{{item.icon}}" ></ion-icon>
<span>
{{item.nama}}
</span>
</ion-card>
</div>
the function is :
openMenu (param : any) {
this.navCtrl.push(param.page);
}
first that I notice is when the page is pushed there is some link that wrote on URL bar http://localhost:8100/#/home/repair-request
I want to ask isn't on angular 2 route had not been running like this I get a bit curious about this can someone explain it to me is it the right one or not...
[]
You have to create an instance of the RouterModule that will execute our desired routing functionality.
After that, you just pass an array of route objects to either the forRoot or forChild methods on the RouterModule.
Also, make sure you are doing useHash to false of RouterModule option.
{ useHash: false }
useHash: enables the location strategy that uses the URL fragment instead of the history API.
Check the following sample code in your app.routes.ts
import { ModuleWithProviders } from '#angular/core';
import { RouterModule } from '#angular/router';
// custom imports
import { Page1Component } from '../pages/page1/page1.component';
import { Page2Component } from '../pages/page2/page2.component';
import { Page3Component } from '../pages/page3/page3.component';
export const APP_ROUTES_PROVIDER: ModuleWithProviders = RouterModule.forRoot(
[
{ path: '', redirectTo: '/page1', pathMatch: 'full' },
{ path: 'page1', component: Page1Component },
{ path: 'page2', component: Page2Component },
{ path: 'page3', component: Page3Component}
] , {useHash: false});
For each route we provide a path and the component that should be rendered at that path. The empty string for the HomeComponent's path means that the HomeComponent will be rendered when there is no URL.
Then, you have simply import our new routing module into the app module.
imports: [
APP_ROUTES_PROVIDER,
IonicModule.forRoot(MyApp)
],
For more help please check this link1 and link2.
Hopes this will help you!!

Passing Value from RouterStateSnapshot to my Root Routing File in Angular 2 App

I am trying to figure out how to pass the value from the RouterStateSnapshot in my auth.guard file to my routing file in my Angular 2 app. I want to do this because, rather than loading a hard-coded default component first, I want, after re-login, for the last active component/page to load up. I have this value in my canActivate() function in my AuthGuard file, because I can console out it out via RouterStateSnapshot. So now I need to figure out how to pass this value on to my root routing file so it, on login/re-login, that component gets loaded.
This is the canActivate() function in my AuthGuard file:
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot)
{
// Get route content id
let contentId = Object.getPropertyValueAtPath(route, 'data.contentId');
console.log(state.url);
// If route does not have session id, don’t load in tab view
if (!String.isNotNullOrEmpty(contentId))
{
console.error(`Route (${route.routeConfig.path}) does not have a content id.`);
this.router.navigateByUrl(''); // Forward to default page.
this.router.navigate([state.url]);
return false;
}
if (this.disabled) return true;
if (sessionStorage.getItem('currentUser'))
{
// logged in so return true
return true;
}
// not logged in so redirect to login page with the return url
this.router.navigate(['/login', {returnUrl: state.url}]);
return false;
}
Notice that I am doing this within that function: console.log(state.url). This gives me the correct value. Now I need to pass it to my app-routing file.
To clarify, currently, on re-login, the last active component is loaded -- but it displays as a background tab, and the default 'redirect' component is what loads up as the active component (i.e, it shows as the active tab).
A simplified version of the app-routing file looks like this:
import { HomeComponent } ...
export const routes: Routes = [
{ path: 'login', component: LoginComponent },
{ path: 'home', component: HomeComponent },
{ path: 'about', component: AboutComponent },
{ path: '**', redirectTo: 'home' }
];
As you can see above, on initial load I currently redirect the user to the 'home component' by default. What I'd like to do is re-direct them to the value that is stored in "state.url" from RouterStateSnapshot. I'm not clear how to do this, however. Any ideas as to how I'd pass that value from my AuthGuard file down to my app-routing file? Can I simply inject RouterStateSnapshot into my app-routing file to get that desired value directly? Or can I use "resolve" here along with the path in routing? What's the recommended way to handle this kind of scenario?
I accomplish this by storing the url in a shared service from my AuthGuard
// auth-guard.ts
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let isLoggedIn = this.authService.isUserLoggedIn();
if(isLoggedIn){
return true;
}else{
this.someService.storeRedirectUrl(state.url);
this.router.navigateByUrl('/login');
return false;
}
}
Then when the user logs in, check if that redirect url was stored and navigate to it
// login method within login page
login(){
this.authService.login(email, password).subscribe(
res => {
// successful user login, so determine where to route user
if(this.someService.redirectUrl){
// redirect url found, navigate to that url
this.router.navigateByUrl(this.someService.redirectUrl);
}else{
// if no redirect url found, navigate to normal landing page
this.router.navigateByUrl('/home');
}
});
}
Routes File
// routes
export const routes: Routes = [
{
path: 'login',
component: LoginComponent
},
{
path: 'home',
component: HomeComponent,
canActivate: [AuthGuard]
},
{
path: 'about',
component: AboutComponent,
canActivate: [AuthGuard]
},
{
path: '**',
redirectTo: 'home'
}
];
Can I simply inject RouterStateSnapshot into my app-routing file to get that desired value directly?
app-routing is just for mapping routes to components, so there is no injecting the route snapshot into it.
Another option you could do is to pass the redirect url as a query parameter of the login page within the auth guard. (I think this was what you were heading towards)
// auth-guard.ts
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): boolean {
let isLoggedIn = this.authService.isUserLoggedIn();
if(isLoggedIn){
return true;
}else{
this.router.navigate(['/login', {redirectUrl: state.url}]);
return false;
}
}
Then the process is the same after a user logs in successfully, except this time you fetch the redirect url from the url parameters instead of the service.

Unable to read Route Parameter in Angular 2

I have successfully implemented route parameter in Angular JS for my other components in same project and for the new component also I am following the same way but It's not working and I am unable to understand the problem in the code.
Below is the code of my routes file
import { Routes, RouterModule } from '#angular/router';
import { CustomerBillComponent } from '../components/customer_bill.component';
const routes: Routes = [
{ path: 'add-bill', component: CustomerBillComponent },
{ path: 'add-bill/:customer_reference', component: CustomerBillComponent },
];
export const routing = RouterModule.forRoot(routes);
(I tried using different routes also, but it didn't work)
Below is the code in My CustomerBillComponent.ts file
ngOnInit() {
//When I visit /#/add-bill/CR452152
let route_location = location['hash'].split('/')[1].toLowerCase();
console.log(route_location); //prints add-bill in Console
var customer_reference = this.route.snapshot.params['customer_reference'];
console.log(customer_reference); //prints undefined
}
Did I miss something
Thanks in advance!!!
You need to add ModuleWithProviders. It's a wrapper for module provider.
import {ModuleWithProviders} from '#angular/core';
export const routing: ModuleWithProviders = RouterModule.forRoot(router);
First try:
this.route.params.subscribe(
(params) => {
console.log(params);
}
)
And see what you get. If that doesn't work it's likely that you try to access a parent route's parameter, in which case you have to step up in the router tree in order to gain access to it.
You can do this with the .parent property, like such:
this.route.parent.params.subscribe(
(params) => {
console.log(params);
}
)
As many times as you need.
I face almost the same problems. But the reason was different.
In my scenario, the lending page(Component Specified on routing) was different and I was trying to access the route params on the parent Route Component.
Below is the code to demonstrate my scenario:
home.module.routing.ts
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
//other import statements...
const routes: Routes = [
{
path: 'home', component: HomeComponent,
children: [
{ path: 'buy/:mainType/:subType', component: BuyComponent, data: {} },
{ path: 'buy/:mainType', component: BuyComponent, data: { } },
{ path: '', redirectTo: 'buy', pathMatch: 'full' },
]
},
{ path: 'checkout', component: CheckoutCartComponent },
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class HomeRoutingModule { }
So, I had to access the RouteParam values in HomeComponent(Parent) and the Lending page was BuyComponent(Child Route of HomeComponent).
So, I was not getting values of route params using below code:
//Inside HomeComponent.ts
ngOnInit() {
this.sub = this.route.params.subscribe(params => {
this.routeText = params['category'];
this.title = this.formatTitle(this.routeText);
});
}
As the lending page is BuyComponent, the above code will not work. Angular allows to access the route params in the above way only on the landing Component.
I tried a lot and finally got a solution to access the Route Params in parent route Component.
Below is the code to access the same:
//Inside HomeComponent.ts
const routeChildren = this.activatedRoute.snapshot.children;
if (routeChildren.length) {
//Your code here to assign route params to the Component's Data Member.
}
So, accessing this.activatedRoute.snapshot.children instead of this.route.params did the trick for me.
Hope this will help if someone lands here in search of the problem like me.
Best Regards.

Resources