1

I am building an angular app. I am navigating from first component to second through click event. While navigating to the second component I am wiling to pass some data from first component to the second component. I have followed a tutorial to achieve this but couldn't do it. Below is my code

First component.ts

export class FirstComponent implements OnInit {

@Output() messageEvent = new EventEmitter<string>();

constructor(){
}

ngOnInit() {}


sendMessagetoSecond(ahu) {
    this.messageEvent.emit(ahu)
    console.log(ahu)
  }

first component.html

<map name="ahuMap">
   <area shape="rect" coords="818,232,917,262" (click)="sendMessagetoSecond()" [routerLink]="['/secondComponent']">
 </map>

second component.ts

ahu : string

receiveMessage($event) {
  this.ahu = $event
}

second component .html

<body>
  <app-first (messageEvent)="receiveMessage($event)"></app-first>
  ahu: {{ahu}}
  <div>
   ....
  </div>
</body>

This is what I tried. The problems I am facing are:
1-Variable is not being transferred to the second component
2-HTML of first component is also being loaded in second component.
Is there something that I am missing or doing wrong?

13
  • In receiveMessage function what do you see if you console.log($event)? Commented Dec 18, 2019 at 9:50
  • 1
    Why do ypu have a [routerLink]="['/secondComponent']" on your area component ? Commented Dec 18, 2019 at 9:51
  • delete the routerLink and route from the sendMessageToSecond Method (after the emit) -> this.router.navigate(['/secondComponent']); Commented Dec 18, 2019 at 9:53
  • for transferring data between siblings or unrelated components use service and observables. Commented Dec 18, 2019 at 10:02
  • 1
    if string length is not big you can directly pass that through route, and if you don't want that string to be seen by others, encrypt it and pass in route Commented Dec 18, 2019 at 10:17

3 Answers 3

5

You can use a shared service to pass data between components. When you have data that changes over time, RxJS BehaviorSubject will be very useful in this case.That it will ensures that the component always receives the most recent data.

To do so,

you need first to create a service in which you will add a private BehaviorSubject that will hold the current value of the message that you want to share between components. And two methods, one to handle the current data stream as an observable that will be used by the components and the other to update the value of the message.

data.service.ts

import { Injectable } from '@angular/core';
import { BehaviorSubject, Observable } from 'rxjs';

@Injectable()
export class DataService {

  private messageSource = new BehaviorSubject('default message');

  constructor() {}

  fetchMessage(): Observable<string> {
    return this.messageSource.asObservable();
  }

  sendMessage(message: string) {
    this.messageSource.next(message)
  }

}

Once the service is created, you need just to inject it in your components' constructor then call its methods fetchMessage/sendMessage in order to get or change your message value.

So,here is how you can use it to pass data from parent to child for example:

parent.component.ts

import { Component, OnInit } from '@angular/core';
import { DataService } from "./data.service";

@Component({
  selector: 'parent',
  template: `
    {{message}}
    <button (click)="newMessage()">send Message</button>
  `
})
export class ParentComponent implements OnInit {

  message:string;

  constructor(private data: DataService) { }

  ngOnInit() {
    this.data.fetchMessage.subscribe(message => this.message = message)
  }

  newMessage() {
    this.data.sendMessage("Hello from Parent Component")
  }

}

child.component.ts

import { Component, OnInit } from '@angular/core';
import { DataService } from "./data.service";

@Component({
  selector: 'child',
  template: `
    {{message}}
  `
})
export class ChildComponent implements OnInit {

  message:string;

  constructor(private data: DataService) { }

  ngOnInit() {
    this.data.fetchMessage().subscribe(message => this.message = message)
  }

}

Hope this may help you.

Sign up to request clarification or add additional context in comments.

Comments

0

in this demo, I am passing a value from app.component.ts to view component.component.ts using test.service

Here, in the constructor of app.component.ts giving a value to a variable which is in test.service, then assigning that value to a variable into view component.component.ts.

Comments

0

The way to do this is using observables. you can use Subject or Behavioral subject as you need. Then you can subscribe from another component and act accordingly. So the implementations are as follows:

@Injectable({ providedIn: 'root' })

export class MessageService { private subject = new Subject();

sendMessage(message: string) {
    this.subject.next({ text: message });
}

clearMessages() {
    this.subject.next();
}

getMessage(): Observable<any> {
    return this.subject.asObservable();
}
}

So in another component you can subscribe like below:

constructor(private messageService: MessageService) {
    // subscribe to home component messages
    this.subscription = this.messageService.getMessage().subscribe(message => {
      if (message) {
        this.messages.push(message);
      } else {
        // clear messages when empty message received
        this.messages = [];
      }
    });
}

And for the emmitting part we can do below:

export class HomeComponent {
constructor(private messageService: MessageService) { }

sendMessage(): void {
    // send message to subscribers via observable subject
    this.messageService.sendMessage('Message from Home Component to App Component!');
}

clearMessages(): void {
    // clear messages
    this.messageService.clearMessages();
}
}

These are just example code picked, You can add multiple subscriptions as you want.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.