Muirik
Muirik

Reputation: 6289

Angular2: Passing Value from One Component to Another

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

Answers (2)

user9903
user9903

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

Rahul Singh
Rahul Singh

Reputation: 19640

make use of @input tag in angular2 this will help you pass information between components

Look at this link for ref

http://www.thoughtdelimited.org/thoughts/post.cfm/learning-angular-2-tour-of-heroes-tutorial-lesson-5

Upvotes: 0

Related Questions