Sakura_Lu
Sakura_Lu

Reputation: 11

how to send message between two same-level component?

I have a Navbar and a Create Course page. I have two components for them: CourseComponent and NavbarComponent.

My problem is that when I enter the Create Course Page, the Navbar Component will add a button that says —— "course saving", when I click the button, it will save the course I have edited. I use the JhiEventManager's broadcast to exchange information. here is my code:

navbar-component

import { JhiEventManager } from 'ng-jhipster';

@Component({
  selector: 'jhi-course',
  templateUrl: './course.component.html',
  styleUrls: ['course.css']
})
export class CourseComponent implements OnInit, AfterViewInit {
  constructor(private eventManager: JhiEventManager) {}
  ngOnInit() {
    this.eventManager.subscribe('COURSE_SAVE_EVENT', msg => {
      console.log('braodcast:  ', msg);
      if (msg.saveCourse) {
        this.saveCourse();
      }
    });
  }

  saveCourse() {
    alert('save course');
  }
}

navbar-component

import { JhiLanguageHelper } from 'app/core';

@Component({
  selector: 'jhi-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['navbar.css']
})
export class NavbarComponent implements OnInit {
  constructor(private eventManager: JhiEventManager) {}
  clickSaveCourseBtn() {
    this.eventManager.broadcast({
      name: 'COURSE_SAVE_EVENT',
      content: 'save the course',
      saveCourse: true,
      publishCourse: false
    })
  }
}

But!!!!!! when I enter the course page three times and click the 'save course' button, it will execute the saving operation three times! I just want it can save the data one time,what should I do?

Upvotes: 1

Views: 488

Answers (2)

T. Shashwat
T. Shashwat

Reputation: 1165

You can use service or Input / Output Decorators to communicate between components inside app same level , parent to child and vice versa.

define your service and import it in your components .ts file then set the data you want to retrieve in other component where you will again import the service and get Data.

in 1st component :

this.eventManager.subscribe('COURSE_SAVE_EVENT', msg => {
      console.log('braodcast:  ', msg);
      if (msg.saveCourse) {
       this.serviceReference.setDta("courseMsg" , msg);
        this.saveCourse();
      }
    });

In 2nd component use this.serviceReference.getData()

and in service of course write setdata and getDta function.

2nd way Using INPUT

< app-messagecomponent [YourInputVariableName]= "YourMessage" >< /app-messagecomponent>

in app.compnent write

YourMessage:any='my Message to be displayed in the messageComponent';

in app-message.component write

@Input YourInputVariableName:any;

you can print message in app-messagecomponent by this.YourInputVariableName

Upvotes: 0

Leon
Leon

Reputation: 480

The problem is that your subscription to the eventManager is still active when your component gets destroyed.

You can use the takeUntil operator from rxjs. That way, you don't have to take care of unsubscribing your subscriptions.

    import { takeUntil } from 'rxjs/operators';
    import { Subject } from 'rxjs';

    export class CourseComponent implements OnInit, OnDestroy {

       private destroy$ = new Subject<void>();

       ngOnInit() {
            this.eventManager.observable.pipe(
                takeUntil(this.destroy$))
                .subscribe('COURSE_SAVE_EVENT', msg => {
                   console.log('braodcast:  ', msg);
                   if (msg.saveCourse) {
                      this.saveCourse();
                }});
        }

        saveCourse(){
           alert('save course');
        }

        ngOnDestroy() {
           this.destroy$.next();
           this.destroy$.complete();
        }
      }

Upvotes: 1

Related Questions