I have app component(for nav header) and auth component(for login).
They need both "isLoggedIn" property which can be useful for app to change its "login" button to "logout" and for auth to block login attempt after login.
But I don't know whether I can export? a property from one component to another.
I know I can use service but app doesn't have proper method to subscribe user service's mapped data.
How can I make them share "isLoggedIn" property?
Here are my auth component and app component with user-authentication service.
export class AuthComponent {
private username = '';
private password = '';
private remembered: boolean = false;
isLoggedIn: boolean;
constructor(private userAuthenticationService: UserAuthenticationService) {}
onsubmit() {
this.userAuthenticationService
.logIn({ username: this.username, password: this.password })
.subscribe(response => {
this.isLoggedIn = response["success"];
});
}
}
//auth.component.html
<div class="loginbox">
<header>MAILBOY</header>
<form *ngIf="!isLoggedIn; else loggedInMessage">
<input type="text" [(ngModel)]="username" name="username" id="email" placeholder="이메일 주소"/>
<input type="password" [(ngModel)]="password" name="password" id="password" placeholder="비밀번호"/>
<label for="remember"><input type="checkbox" id="remember" [checked]="remembered" (change)="remembered = !remembered" />이메일 저장</label>
<button class="login" (click)="onsubmit()">로그인</button>
<h3>처음이신가요?</h3><button class="register"><a href="/register">회원가입</a></button>
</form>
<ng-template #loggedInMessage>
<h1>환영합니다! 메일 수신 여부를 설정해주세요.</h1>
</ng-template>
</div>
export class AppComponent {
isLoggedIn = 'false';
constructor(private userAuthenticationService: UserAuthenticationService) { }
}
//app.component.html
<div class="headerSpacing">
<nav>
<a routerLink="/home" routerLinkActive="active">홈</a>
<a *ngIf="isLoggedIn; else loggedInMessage" routerLink="/auth" routerLinkActive="active">로그인</a>
<ng-template #loggedInMessage>
<a (click)="logOut()">로그아웃</a>
</ng-template>
<a routerLink="/mail-setting" routerLinkActive="active">메일 수신 설정</a>
</nav>
</div>
<router-outlet></router-outlet>
finally my user-authentication service
@Injectable()
export class UserAuthenticationService {
headers = new Headers({
'Content-Type': 'application/json'
});
constructor(private http: Http) { }
/*
body: {
username,
password,
}
*/
logIn(user: Object) {
return this.http
.post('/auth/login', JSON.stringify(user),
{ headers: this.headers })
.map(data => { console.log(data);
return data.json() });
}
private handleError(error: any): Promise<any> {
console.log('An error occurred ', error);
return Promise.reject(error.message || error);
}
}
You can use a BehaviorSubject here.
In UserAuthenticationService:
import { BehaviorSubject } from 'rxjs';
export class UserAuthenticationService {
private loggedIn = new BehaviorSubject(false);
// call this when you want to set loggedIn to true
login() {
this.loggedIn.next(true);
}
getIsLoggedIn() {
return this.loggedIn;
}
}
In app or auth component or any component that you need the value you can subscribe to it:
constructor(private userAuthenticationService: UserAuthenticationService) {
userAuthenticationService.getIsLoggedIn().subscribe(bool => {
// use bool value here, you can set local var
// this.isLoggedIn = bool;
});
}