url changes but angular does not navigate - javascript

I have 2 links like below. When I click on any one the first time, it navigates to it but when I click on the second link after that, the url changes but it does not navigate to it.
<li><a routerLink="/order/buyer" >Buyer</a></li>
<li><a routerLink="/order/seller">Seller</a></li>
These are my route configuration:
app.routing.module.ts
const routes: Routes = [
{
path: '',
pathMatch: 'full',
component: RootComponent,
},
{
path: '',
children: [
{
path: 'order',
loadChildren: './order/order.module#OrderModule',
}
]
}
order.module.ts
export const ROUTES: Routes = [
{
path: ':orderParty/:id',
component: OrderDetailComponent,
canDeactivate: [OrderDetailGuardService]
},
{
path: ':orderParty',
component: OrderListComponent
}
];
Tried several things, that out there but didn't work. What I have noticed is on the second click, the ngOnInit() of the 'OrderListComponent' does not get called.

You have a few options to solve this common issue in Angular, the most common one is using the solution on this GitHub thread:
https://github.com/angular/angular/issues/13831#issuecomment-319634921
constructor(private router: Router){
// override the route reuse strategy
this.router.routeReuseStrategy.shouldReuseRoute = function(){
return false;
}
this.router.events.subscribe((evt) => {
if (evt instanceof NavigationEnd) {
// trick the Router into believing it's last link wasn't previously loaded
this.router.navigated = false;
// if you need to scroll back to top, here is the right place
window.scrollTo(0, 0);
}
});
}
Another solution would to subscribe to your router params and handle change based on the new param like this article suggests:
this.activeRoute.params.subscribe(routeParams => {
this.loadUserDetail(routeParams.id);
});
https://medium.com/#mvivek3112/reloading-components-when-change-in-route-params-angular-deed6107c6bb

Yes, because route is same its the dynamic parameter that is changing. to read changed parameter you can inject router in construct and read parameter like
this.router.params.subscribe((params)=>{console.log(params)});
The route is pointing to same component hence its not re initializing.

Related

Best way to check what page you're on in Vue.js

I have
these simple route/URL when I am in a car details page
http://localhost:8080/car/1
I am using vue2; what is the best way to check if I am on a car page?
I normally
would have checked for the first segment of the URL, but I wasn't sure if that is the best future-proof approach.
Questions
Should I use JS to detect what page I am ?
Should I use Vue functionality to access the router object?
Why would one decide to pick one over another?
You could provide a name for your route inside the routes definition like :
{
path: '/car/{id}',
name: 'car',
component: CarView
},
then access it using this.$route.name or you could parse the this.$route.path to get the name using String object methods
Perhaps, try using: router.currentRoute.path, where router is:
import Router from "vue-router";
Vue.use(Router);
const routes = [
{ path: "/", component: Home },
{ path: "/test1", component: Test1 },
{ path: "/test2", component: Test2 }
];
const router = new Router({
routes
});
console.log('Current route: ', router.currentRoute.path);

angular 14 default router with param

I created an angular app with the last version, i updated the base href to /popup to have the url http://localhost:4200/popup
i want, when the application opens in the url http://localhost:4200/popup, it redirects me to a 404 page, but when i add a param in the url http://localhost:4200/popup/444444444 is opens a specific page.
I tried with the below code but i have this error:
main.ts:13 Error: NG04014: Invalid configuration of route
'/:requestNumber': path cannot start with a slash
<base href="/popup" />
export const routes: Routes = [
{ path: '', redirectTo: '/:requestNumber', pathMatch: 'full' },
{
path: '/:requestNumber',
component: AppComponent,
resolve: { payment: PaymentResolverService },
},
];
I added the resolver to check if the url has a param requestNumber or not.
The question isn't clear. If I understood you right - you can't expect a route with /popup/444444 to be caught by an empty path (because it is not an empty path, because it has 44444 in it), therefore, you can't write this:
{ path: '', redirectTo: '/:requestNumber', pathMatch: 'full' }
The path configuration above picks up empty paths, i.e. /popup/, when you want it to redirect to /popup/:requestNumber, where will it get the request number from?? (remember, the path that got you here was /popup/)
You can write this though, where empty paths are redirected to a 404 page:
export const routes: Routes = [
{
path: '',
component: Some404Page,
},
{
path: ':requestNumber',
redirectTo: 'popup/:requestNumber',
pathMatch: 'full',
},
{
path: 'popup/:requestNumber',
component: AppComponent,
resolve: { payment: PaymentResolverService },
},
];
Since this is the only hit on Google, I'll just add a side-answer.
I was getting this error for apparently this route:
{
path: 'stuff/moduleA',
loadChildren: () => import('./modules/module-a/module-a.module').then(m => m.module-a)
},
Which didn't make sense since there's clearly no leading slash there. The problem was actually that this lazily loaded module contained a route that looked like this:
{
path: '/',
component: AComponent,
},
The fix was to change this path by changing it to path: ''.
So check the routes inside of the loaded module, even if that route isn't mentioned in the error.

How to fully reload an Angular component only when user is logged in?

In my Angular project I've got:
SignInComponent -> Handling the login requests
DashboardComponent -> Displayed for all children when user has successfully logged in
HomeComponent -> The actual content/page that will be displayed to the user - A child of 'DashboardComponent'
And it looks like:
export const appRoutes: Routes = [
{
path: 'login', component: SignInComponent
},
{
path: '', component: DashboardComponent,
children: [
{ path: '', component: HomeComponent },
],
canActivate: [AuthGuard]
},
{
path: '', redirectTo: '/login', pathMatch: 'prefix'
}
]
Now the problem that I'm facing, is that when the user is successfully logged in, that it won't reload the component 'DashboardComponent'. And I'm not referring to the routes itself (those are going fine). But there's one needed JS script not loaded which blocks the user from expanding the menu item(s). See below:
However, when you manually reload the page, it will work. The menu item(s) will expand. See below:
So, fully reloading the component would do the trick, but I only want that when it's matching with the previous 'route', in this case '/login'. In other words, I would to fully reload the 'DashboardComponent', only when it's not a 'child'. How could I apply this?
Or is there perhaps a better and easier approach?
Here it looks some url match problem because you have defined path:'' to dashboard also making that path to redirect to login with next routing object in routes array
export const appRoutes: Routes = [
{
path: 'login', component: SignInComponent
},
{
path: 'dashboard', component: DashboardComponent,
children: [
{ path: 'home', component: HomeComponent },
],
canActivate: [AuthGuard]
},
{
path: '', redirectTo: '/login', pathMatch: 'prefix'
}
]
So change it like above code and try. This will not make any url confusion and redirection will take place properly
Update:
It seems that custom code (JS) is being called on document ready event. That explains why it's working the only first time. See comment: https://stackoverflow.com/a/46349639/2318669.
What I've done to solve it:
I declared a variable:
declare const openMobileMenu: any;
And then I bind it from the component:
onMobile() {
openMobileMenu();
}
To the following method in the JS file:
function openMobileMenu() {
$(".horizontal-menu .bottom-navbar").toggleClass("header-toggled");
};
Thanks anyway for the support! :)
I appreciate it.

Vue js router: how to change or update URL query on click event

I am trying to change/update the router query on click event in my navigation. But no matter what I do, the click event don't change the query in URL.
But in the vue in-component guard "beforeRouteUpdate" I get the new parameters if I console.log(to.query.scrollto);
Maybe someone have an idea or a better solution how I can fix this?
This is my intention:
myhomepage.de/?scrollto=about
myhomepage.de/?scrollto=contact
myhomepage.de/otherpage/?scrollto=about
myhomepage.de/anotherpage/?scrollto=service
...
These are my settings:
Router settings:
export default new Router({
mode: 'history',
base: __dirname,
routes: [
{
path: '/',
name: 'home',
component: Page
},
{
path: '*',
component: NotFound
}]
})
My navigation links:
a(href="" #click.prevent="updateNav(item.key)") {{item.title}}
In my methods:
updateNav(query) {
var data = Object.assign({}, this.$route.query);
data['scrollto'] = query;
this.$router.push({name: 'home', query : data });
...
}

Vue router inherit parent properties

I'm fairly new to vue.js and I'm currently trying to setup my different routes. I'm using sub routes, since the "logged in" user will have a different UI than a visitor.
Currently my setup is like this:
routes: [
{
path: '/auth',
name: 'auth',
component: test,
meta: {
auth: false
},
children: [
{
path: 'login',
name: 'login',
component: login
},
{
path: 'signup',
name: 'signup',
component: signup
}
]
},
{
path: '/user',
name: 'user',
component: test,
meta: {
auth: true
},
children: [
{
path: 'profile',
name: 'profile',
component: login
}
]
}
]
While this is working, I'm wondering why child routes don't take over the parents meta properties. Do I need to assign the meta.auth to each sub route? Or is there any way to inherit this?
Essentially in the router.beforeEach, I want to check if the user is authenticated correctly or not. But only on child routes of /user
I'm also coming from an angular background, so I'm used to nesting routes, not sure if this is the best way in Vue.
To answer my own question: https://github.com/vuejs/vue-router/issues/704
I didn't realise this was deprecated in Vue-router 2.0, it is possible to get the matched route and find the meta there.
With vue-router v.3 to match parent's meta (for example: in beforeEach() func. ) You need to use to.matched.some() like this:
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.auth)) {
// ...
next({name:'route-name'})
} else {
next()
}
}
https://router.vuejs.org/guide/advanced/meta.html

Categories