Reputation: 6289
I have successfully implemented a login service for my Angular 2 app. What I want to do now is provide the username of the logged-in user from that component to a separate component - specifically the chat component.That way I can display the user's name when they are chatting with another user. I'm still a little hazy on how you pass values like this from one component to another in Angular 2. Here is the code from my login component:
import { AuthenticationService } from './../../data/authentication.service';
import { AlertService } from './../../data/alert.service';
import { Component, OnInit, Output } from '@angular/core';
import { Router } from '@angular/router';
@Component({
selector: 'app-login',
templateUrl: 'app/views/login/login.component.html',
styleUrls: ['app/views/login/login.component.css']
})
export class LoginComponent implements OnInit {
//@Output() username;
model: any = {};
loading = false;
constructor(
private router: Router,
private authenticationService: AuthenticationService,
private alertService: AlertService) { }
ngOnInit() {
// reset login status
this.authenticationService.logout();
}
login() {
this.loading = true;
this.authenticationService.login(this.model.username, this.model.password)
.subscribe(
data => {
this.router.navigate(['/']);
console.log('User logged in as: ' + this.model.username);
},
error => {
this.alertService.error(error);
this.loading = false;
});
}
reqPasswordReset() {
let popup = document.getElementById('myPopup');
popup.classList.toggle('show');
}
}
This component make use of an authentication service, which looks like this:
import { LoginComponent } from './../views/login/login.component';
import { ContextMenu } from './../ui/context-menu.component';
import { Router, RouterLinkActive } from '@angular/router';
import { Injectable } from '@angular/core';
import { Http, Headers, Response } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
@Injectable()
export class AuthenticationService {
constructor(private http: Http) {}
login(username: string, password: string) {
return this.http.post('/api/authenticate', JSON.stringify({ username: username, password: password }))
.map((response: Response) => {
// login successful if there's a jwt token in the response
let user = response.json();
if (user && user.token) {
// store user details and jwt token in local storage to keep user logged in between page refreshes
localStorage.setItem('currentUser', JSON.stringify(user));
}
});
}
isAuthenticated() {
if (localStorage.getItem('currentUser')) {
//console.log('User successfully authenticated...');
return true;
} else {
// console.log('User is not authenticated...');
return false;
}
}
logout() {
// remove user from local storage to log user out
localStorage.removeItem('currentUser');
console.log('User successfully logged out');
}
}
I'm able to successfully log to the console the username, so I know I'm capturing that value. What I'd like to do is now pass that value from "this.model.username" to my room component, which currently looks like this:
import { ChatService } from './../chat/chat.service';
import { User } from './../../views/user/user';
import { Component, OnInit, Input } from '@angular/core';
import { AuthenticationService } from './../../data/authentication.service';
import { Http, Headers, Response } from '@angular/http';
import { Router } from '@angular/router';
@Component({
selector: 'app-room',
templateUrl: './room.component.html',
styleUrls: ['./room.component.less']
})
export class RoomComponent implements OnInit {
otherImg = 'app/img/photo-ph.png';
// otherImg = 'app/img/portrait-place-holder.svg';
model: any;
loading = false;
others = [
{ id: 1, name: 'John Smith', avatar: 'app/img/photo-ph.png' },
{ id: 2, name: 'Javier Sanchez', avatar: 'app/img/photo-ph.png' }
];
user;
token;
name;
nickname;
constructor(private authenticationService: AuthenticationService,
private router: Router,
private http: Http,
private chatService: ChatService) { }
isLoggedIn() {
this.loading = true;
if (this.authenticationService.isAuthenticated()) {
return true;
}
}
gotoChat() {
this.chatService.gotoChat(this.user);
}
ngOnInit() {
}
}
The view for this component is looping through users (others) and displaying an icon for each "other" user. Here is that code:
<div *ngIf="isLoggedIn()" class="others">
<span *ngFor="let other of others"><i [ngClass]="'material-icons'" (click)="gotoChat()" [routerLink]="['/chat']">person</i></span>
<a [routerLink]="['/login']">Logout</a>
</div>
The ultimate goal here is for people to see others that are logged in, and be able to initiate a chat with them.
Where I'm stuck is in how to pass the value (this.model.username) that I'm capturing in the login component, down to the room component.
Upvotes: 1
Views: 825
Reputation:
In the login method of your AuthenticationService you're storing the user object in local storage, you should also store it in the authentication service so that when it is injected into the component, you are able to access the user object.
You will need to add another method called getUsername to the AuthenticationService to get the username.
It will look something like this:
@Injectable()
export class AuthenticationService {
private username: string;
constructor(private http: Http) {}
login(username: string, password: string) {
return this.http.post('/api/authenticate', JSON.stringify({ username: username, password: password }))
.map((response: Response) => {
// login successful if there's a jwt token in the response
let user = response.json();
if (user && user.token) {
// store user details and jwt token in local storage to keep user logged in between page refreshes
localStorage.setItem('currentUser', JSON.stringify(user));
// store username
this.username = user.username;
}
});
}
getUsername(): string {
return this.username;
}
Upvotes: 1
Reputation: 19640
make use of @input tag in angular2 this will help you pass information between components
Look at this link for ref
Upvotes: 0