I m facing very strange issue. My angular application page is displaying properly. It seems its not fully loaded, and when I m manually reloading/refreshing the page, its loading fine.
Here is the full scenario. I created a login page which displays perfectly and working as expected. After login I m navigating to my dashboard page which is not showing properly, seems half loaded, but when manually refresh its work fine. After inspecting elements, I found that the contents of dashboard is there but not showing properly. there is no any error in console as well
Here is my app-routing.module.ts code:
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { LoginComponent } from './login/login.component';
import { MainLayoutComponent } from './main-layout/main-layout.component';
const routes: Routes = [
{ path: 'login', component: LoginComponent },
{ path: 'dashboard', component: MainLayoutComponent },
{ path: '', pathMatch: "full", redirectTo: 'dashboard' },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
And here is my login.component.ts
declare var $: any;
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Common } from '../Common/common';
import { Router } from '@angular/router';
@Component({
selector: 'app-login',
templateUrl: './login.component.html',
styleUrls: ['./login.component.css'],
encapsulation: ViewEncapsulation.None
})
export class LoginComponent implements OnInit {
constructor(private httpClient: HttpClient, private router: Router) { }
form: any;
submitModel: any = {
username: "",
password: ""
};
ngOnInit(): void {
this.form = $('#myloginform').parsley();
localStorage.clear();
}
SubmitForm() {
if ($("#myloginform").parsley().validate()) {
$(".preloader").show();
this.httpClient.post<any>(Common.APIUrl "login", this.submitModel, { withCredentials: true }).subscribe(
{
next: data => {
console.log(data);
localStorage.setItem("token", data.result);
this.router.navigate(['dashboard']);
},
error: error => {
console.error(error);
},
complete: function () {
console.log("complete");
$(".preloader").hide();
}
}
);
}
}
}
Here is my main-layout.component.ts
declare var $: any;
import { HttpClient } from '@angular/common/http';
import { Component, OnInit, ViewEncapsulation } from '@angular/core';
import { Router } from '@angular/router';
import { Common } from '../Common/common';
@Component({
selector: 'app-main-layout',
templateUrl: './main-layout.component.html',
styleUrls: ['./main-layout.component.css'],
encapsulation: ViewEncapsulation.None
})
export class MainLayoutComponent implements OnInit {
constructor(private httpClient: HttpClient, private router: Router) { }
ngOnInit(): void {
console.log("MainLayoutComponent - on init called")
}
Logout() {
$(".preloader").show();
this.httpClient.get<any>(Common.APIUrl "logout", { withCredentials: true }).subscribe(
{
next: data => {
localStorage.clear();
this.router.navigate(['login']);
},
error: error => {
console.error(error);
},
complete: function () {
$(".preloader").hide();
}
}
);
}
}
Currently facing like this:
Expected result:
Additional Info: when I m logging out, its navigating to Login page properly. I have added all references of jQuery/Bootstrap additional plugin in my index html page.
I m new to angular and this is my first question in StackOverflow. Please forgive me, if I couldn't explain better. Thanks in advance
I removed the content from Dashboard and just added one <h1> tag. it is displaying
Index.html
<!DOCTYPE html>
<html dir="ltr" lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- Tell the browser to be responsive to screen width -->
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="robots" content="noindex,nofollow">
<base href="/">
<title>Employee App</title>
<!-- Favicon icon -->
<link rel="icon" type="image/png" sizes="16x16" href="assets/images/favicon.png">
<!-- Custom CSS -->
<link href="assets/dist/css/style.min.css" rel="stylesheet">
<link href="assets/dist/css/style.extended.css" rel="stylesheet">
</head>
<body>
<app-root></app-root>
<script src="assets/libs/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap tether Core JavaScript -->
<script src="assets/libs/popper.js/dist/umd/popper.min.js"></script>
<script src="assets/libs/bootstrap/dist/js/bootstrap.min.js"></script>
<!--Parsley -->
<script src="assets/extra-libs/parsley/parsley.js"></script>
<!-- apps -->
<script src="assets/dist/js/app.min.js"></script>
<script src="assets/dist/js/app.init.js"></script>
<script src="assets/dist/js/app-style-switcher.js"></script>
<!-- slimscrollbar scrollbar JavaScript -->
<script src="assets/libs/perfect-scrollbar/dist/perfect-scrollbar.jquery.min.js"></script>
<script src="assets/libs/jquery-sparkline/jquery.sparkline.min.js"></script>
<!--Wave Effects -->
<script src="assets/dist/js/waves.js"></script>
<!--Menu sidebar -->
<script src="assets/dist/js/sidebarmenu.js"></script>
<!--Custom JavaScript -->
<script src="assets/dist/js/feather.min.js"></script>
<script src="assets/dist/js/custom.min.js"></script>
</body>
</html>
MainLayout.component.html
<div id="main-wrapper">
<header >
<nav >
<div >
<a href=""><i ></i></a>
<a href="">
<b >
<img src="../assets/images/logo-icon.png" alt="homepage" />
<img src="../assets/images/logo-light-icon.png" alt="homepage" />
</b>
<span >
<img src="../assets/images/logo-text.png" alt="homepage" />
<img src="../assets/images/logo-light-text.png" alt="homepage" />
</span>
</a>
<a href="" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation"><i ></i></a>
</div>
<div id="navbarSupportedContent">
<ul >
<li ><a href="" data-sidebartype="mini-sidebar"><i ></i></a></li>
</ul>
<ul >
<li >
<a href="" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"><img src="../assets/images/users/1.jpg" alt="user" width="31"></a>
<div >
<div >
<div ><img src="../assets/images/users/1.jpg" alt="user" width="80"></div>
<div >
<h4 >Steave Jobs</h4>
<p >[email protected]</p>
<a href="profile.html" >View Profile</a>
</div>
</div>
<a href="" (click)="Logout()"><i ></i> Logout</a>
</div>
</li>
</ul>
</div>
</nav>
</header>
<aside >
<div >
<nav >
<ul id="sidebarnav">
<li ><i ></i> <span >Personal</span></li>
<li >
<a href="" aria-expanded="false"><i data-feather="link" ></i><span >Sample Link</span></a>
</li>
<li >
<a href="" aria-expanded="false"><i data-feather="map" ></i><span >Sample Link</span></a>
<ul aria-expanded="false" >
<li ><a href="map-google.html" ><i ></i><span >Google Maps</span></a></li>
<li ><a href="map-vector.html" ><i ></i><span >Vector Maps</span></a></li>
</ul>
</li>
<li >
<a href="" aria-expanded="false"><i data-feather="git-pull-request" ></i><span >Multi level dd</span></a>
<ul aria-expanded="false" >
<li ><a href="" ><i ></i><span >item 1.1</span></a></li>
<li ><a href="" ><i ></i><span >item 1.2</span></a></li>
<li >
<a href="" aria-expanded="false"><i ></i> <span >Menu 1.3</span></a>
<ul aria-expanded="false" >
<li ><a href="" ><i ></i><span > item 1.3.1</span></a></li>
<li ><a href="" ><i ></i><span > item 1.3.2</span></a></li>
<li ><a href="" ><i ></i><span > item 1.3.3</span></a></li>
<li ><a href="" ><i ></i><span > item 1.3.4</span></a></li>
</ul>
</li>
<li ><a href="" ><i ></i><span > item 1.4</span></a></li>
</ul>
</li>
</ul>
</nav>
</div>
<div >
<a href="" data-toggle="tooltip" title="Settings"><i ></i></a>
<a href="" data-toggle="tooltip" title="Email"><i ></i></a>
<a href="" data-toggle="tooltip" title="Logout"><i ></i></a>
</div>
</aside>
<div >
<!--<router-outlet></router-outlet>-->
<footer >
© 2020 Monster Admin by wrappixel.com
</footer>
</div>
</div>
CodePudding user response:
Where you localStorage.getItem("token")? where you're use?.
If you use in the MainLayoutComponent I imagine you get in the ngOnInit of this component.
If you're use in other component -perhafs in the main.component that is who has the <router-outlet>
- already loaded you need indicate to Angular that localStorage has changed. Generally you can use a Subject of one service. That's:
Imagine you has a service. As you should makes all the calls in a service, not in a component, you can have a services like
@Injectable({
providedIn: 'root',
})
export class LoginService {
login$:Subject<bool>=new Subject<bool>()
constructor(private httpClient:HttpClient) { }
login(model:any)
{
return this.httpClient.post<any>(Common.APIUrl "login", model, { withCredentials: true })
.pipe(tap(()=>{
this.login$.next(true); //<--makes subject "next"
})
);
}
logout()
{
return this.httpClient.get<any>(Common.APIUrl "logout", { withCredentials: true })
.pipe(tap(()=>{
this.login$.next(false); //<--makes subject "next"
})
)
}
See that the functions return an observable -the call to your API-
When you subscribe to your LoginService -replace the httpClient.get by this.loginService.login() and this.loginService.logout()-
SubmitForm() {
if ($("#myloginform").parsley().validate()) {
$(".preloader").show();
this.loginService.login(this.submitModel)
.subscribe(
{
..your code..
})
);
}
}
And
Logout() {
$(".preloader").show();
this.loginService.logOut().subscribe(
{
...your code
}
);
}
See that, the "subject" change. So in the component where you need the information of the token you can subscribe to this subject and read the token
this.loginService.login$.subscribe((res:boolean)=>{
..make something to updte the "login"
})
CodePudding user response:
Thank you @The Head Rush for putting me right direction. I m using a bootstrap theme which is not designed for Angular. After digging some Theme js files, I saw some code which is using jQuery code to implement some classes on runtime based on Theme selection. I just called its theme setting function back again, and its works. In my mainlayout component init function, I added this code
ngOnInit(): void {
$("#main-wrapper").AdminSettings();
}