Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular refresh the application if the URL is written manually

I'm using Angular 6 and I have an issue with the change of routes. If I navigate through the application using the routerLink or the navigate() method, it works correctly, because it only load the new module (if necessary). But for example if I am in this link: localhost:8080/home, I click on the URL, cancel the 'home', write 'profile' and press Enter, it correctly goes on profile page but the application in reloaded (also the app component). Why? I can't figure out. This is my routing:

const appRoutes: Routes = [
  { path: 'home', component: HomeComponent, canActivate: [AuthGuard] },
  { path: 'profile', component: ProfileComponent, canActivate: [AuthGuard] },
  { path: 'login', component: LoginComponent },
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  { path: '**', component: PageNotFoundComponent }
];

@NgModule({
  imports: [
    RouterModule.forRoot(appRoutes, { preloadingStrategy: PreloadAllModules })
  ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

Maybe the issue is on the auth-guard?

@Injectable()
export class AuthGuard implements CanActivate {

constructor(private store: Store<fromApp.AppState>, private route: ActivatedRoute, private router: Router) {
}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
    return this.store.select('auth')
        .pipe(take(1),
            map((authState: fromAuth.State) => {
                if (authState.authenticated) {
                    return true;
                } else {
                    let sessionStorageToken: string = sessionStorage.getItem('token');
                    if (sessionStorageToken) {
                        this.store.dispatch(new AuthActions.Login());
                        this.store.dispatch(new AuthActions.SetToken(sessionStorageToken));
                        return true;
                    } else {
                        let url = state.url;
                        this.router.navigate(['/login', { redirectTo: url }]);
                        return false;
                    }
                }
            }));
}
}

This is profile.module.ts:

@NgModule({
declarations: [
    ProfileComponent
],
imports: [
    CommonModule,
    FormsModule
]
 })
 export class ProfileModule { }
like image 983
panagulis72 Avatar asked Jul 04 '18 08:07

panagulis72


3 Answers

you can use

RouterModule.forRoot(
  ROUTES,
  { useHash: true }
)],

The hash will prevent application from reloading. So when you will hit enter on address bar, application will just change the component to display.

like image 78
LETOURNEUR Léo Avatar answered Oct 22 '22 03:10

LETOURNEUR Léo


When you're navigating through the routerLink within Angular, the underlying JavaScript is determining what to serve to the browser. Meaning that when the URL address is changed via the Angular router, it picks up the change and serves the components accordingly.

When you update the URL manually and press enter, it is like going to a new web page. Meaning that the server will need to re-serve the base website, http://localhost:1234, and then the application will handle the route there after, /profile and serve the required component.

I've tried to explain it in a very simplistic way, for a more thorough explanation please check out the Angular docs

like image 37
Wesley Coetzee Avatar answered Oct 22 '22 03:10

Wesley Coetzee


When the routerLink is used, the JavaScript changes the URL , i.e., it is not regarded as reload of the web page.

However, when you hit an enter in the address bar, the page is reloaded, i.e., the content is again served from the server which serves the index.html (if you do not have any other HTML defined to be served in place of index) and hence the application reinitializes.

That is why all the components get reloaded.

As suggested by @Wesley, you can refer to the angular docs for more information.

https://angular.io/guide/router

You may explore the below mentioned blog for deployment purpose.

https://arjunphp.com/deploy-angular-app-production-nginx/

The main thing to notice here is try_files $uri $uri/ /index.html =404;. When an enter is hit on the address bar, NGINX first checks if the given URL maps to some file / route on the server. If it does not exist, which in our case localhost:8080/profile, does not as there is no such physical path. Hence, NGINX would serve the /index.html file, which in turn would fetch all JS files which would in turn handle the routing.

If you need to work with the API, you can use NGINX's reverse proxy mechanism to redirect for example, /api/ path to your corresponding server.

like image 42
Ankit Sharma Avatar answered Oct 22 '22 03:10

Ankit Sharma