2

I have the following scenario in my Angular app:

A component MainDashboardComponent that is visible when I have the route /. Obviously I have the <router-outlet> tag in my app.component.html file, which looks like this:

<app-side-menu></app-side-menu>
<div class="main-container">
  <div class="content">
    <router-outlet></router-outlet>
  </div>
</div>

As you can see I have a SideMenuComponent I use to have a side menu on all my routes. In MainDashboardComponent I have a method that for some reason needs to toggle a chat element that is situated on the side menu. Inside the SideMenuComponent I have a method that handles the visibility toggle for the chat element and it works as expected. How can I call this method from my MainDashboardComponent and toggle the chat element from there?

What I tried with no success

I tried to inject the SideMenuComponent inside my MainDashboardComponent but, though the method toggleChat() is called, the element doesn't change it's visibility. Looks like I have a kind of multiple instance of the same component I guess...

Can you please help me with this? Thank you!

MainDashboardComponent

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-main-dashboard',
  templateUrl: './main-dashboard.component.html',
  styleUrls: ['./main-dashboard.component.scss']
})
export class MainDashboardComponent implements OnInit {

  constructor() { }

  ngOnInit() {}

  setFocus(id) {
    // here I'd like to call SideMenuComponent togglechat() ... 
  }
}

SideMenuComponent

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-side-menu',
  templateUrl: './side-menu.component.html',
  styleUrls: ['./side-menu.component.scss']
})
export class SideMenuComponent implements OnInit {

  showChat: boolean;

  constructor() {
    this.showChat = false;
  }

  ngOnInit() {
  }

  toggleChat() {
    this.showChat = !this.showChat;
  }

}
6
  • can you add full code for that Commented Oct 23, 2018 at 9:52
  • which is your MainDashboardComponent ? Is MainDashboardComponent one of the route? Commented Oct 23, 2018 at 9:53
  • I've update my question :) Commented Oct 23, 2018 at 9:57
  • you can make toggleChat() method to static and in setFocus(id) { SideMenuComponent.toggleChat() Commented Oct 23, 2018 at 10:00
  • 1
    You can also take the leverage of rxjs BehaviorSubject Commented Oct 23, 2018 at 10:13

3 Answers 3

6

To communicate between different components, there are different ways.

  • If you want to communicate between parent and child component, you can use EventEmitter to emit event from child component and handle the event in your parent component
  • If you want to communicate between any components, you can use Service and implement communication with the help of EventEmitter or Subject/BehaviorSubject

In your case, we can create a service, myService.ts and declare and eventEmitter

.service.ts

@Injectable()
export class AppCommonService {

 toggle : EventEmitter<boolean> = new EventEmitter<boolean>()

}

mainDashboard.component.ts

constructor(private myService : myService){}

chatStatus : boolean = false;
ngOnInit(){
 this.myService.toggle.subscribe(status=>this.chatStatus = status);
}

toggleChat(){
 this.myService.toggle.emit(!this.chatStatus);
}

sideMenu.component.ts

constructor(private myService : myService){}

chatStatus : boolean = false;

ngOnInit(){
  this.myService.toggle.subscribe(status=>this.chatStatus = status);
}
Sign up to request clarification or add additional context in comments.

1 Comment

Great and simple solution! Exactly what I was looking for! I never had a case like this and never thought how to do this kind of things, will keep it in mind from now on :) Thank you Sarthak!
0

You could efficiently use child to parent communication in this scenario. You'll need to create a custom event using angular's EventEmitter in your SideMenuComponent and use it in your MainDashboardComponent.

So, here is some code that may help you -

// SideMenuComponent
import { Component, OnInit } from '@angular/core';
@Component({
    selector: 'app-side-menu',
    templateUrl: './side-menu.component.html',
    styleUrls: ['./side-menu.component.scss']
})
export class SideMenuComponent implements OnInit {
    @Output() valueChange = new EventEmitter();
    showChat: boolean;

    constructor() {
        this.showChat = false;
    }

    ngOnInit() {
    }

    toggleChat() {
        this.showChat = !this.showChat;
        this.valueChange.emit(this.showChat);
    }

}

// MainDashboardComponent
import { Component, OnInit } from '@angular/core';
@Component({
    selector: 'app-main-dashboard',
    template: `<app-side-menu (valueChange)='setFocus($event)'></app-side-menu>`
    styleUrls: ['./main-dashboard.component.scss']
})
export class MainDashboardComponent implements OnInit {

    constructor() { }

    ngOnInit() { }

    setFocus(event) {
        // check for required input value 
        console.log(event);
    }
}

Refer these tutorials if required - https://dzone.com/articles/understanding-output-and-eventemitter-in-angular, https://angular-2-training-book.rangle.io/handout/components/app_structure/responding_to_component_events.html

Comments

0

Generally this is the domain of a service!

  • Just create a service and add the "showCat" property.
  • Inject the service into both components
  • Alter SideMenuComponent to:

    toggleChat() {
        this.myService.showChat = !this.myService.showChat;
    }
    
  • Alter MainDashboardComponent, also use this.myService.showChat to show / hide your chat window

Service TS

@Injectable()
export class MyService{
  showCat:boolean = true
}

MainDashboardComponent

toggleChat() {
   this.myService.showChat = !this.myService.showChat;
}

SideMenuComponent

chatVisiblity = this.myService.showCat //<-- bind this to the element attribute

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.