Search code examples
angularangular2-servicesangular2-nativescriptnativescript-telerik-uiinjectable

Calling methods between components in angular using service not working


I am trying to call a method in one component from other component using injectable service

My first component (I'm calling method in other component from this component)

bottombar.component.ts

import { Component, ElementRef, OnInit, ViewChild, AfterViewInit, ChangeDetectorRef, EventEmitter, Input, Output } from "@angular/core";
import { Router } from "@angular/router";
import { Label } from "ui/label";
import { BottomBarService } from '../../services/bottombarservice/bottombar.service';

@Component({
  selector: "bottom-bar",
  templateUrl: "./components/bottombar/bottombar.html",
  styleUrls:["./components/bottombar/bottombar-common.css", "./components/bottombar/bottombar.css"],
  //providers: [BottomBarService]
})

export class bottombarComponent implements OnInit {

  constructor(private bottomBarService: BottomBarService) {

  }

  openDrawer(){
    this.bottomBarService.callSideDrawerMethod();
  }
  ngOnInit() {}


}

From the above component I'm trying to call a method in SideDrawerGettingStartedComponent which is present below which will trigger a method that opens side drawer

My Second component (In which the called method is present)

sidedrawer.component.ts

import { Component, ViewChild, OnInit, AfterViewInit, ChangeDetectorRef } from "@angular/core";
import { Page } from "ui/page";
import { ActionItem } from "ui/action-bar";
import { Observable } from "data/observable";
import { RadSideDrawerComponent, SideDrawerType } from "nativescript-telerik-ui-pro/sidedrawer/angular";
import { RadSideDrawer } from 'nativescript-telerik-ui-pro/sidedrawer';
import { BottomBarService } from '../../services/bottombarservice/bottombar.service';

@Component({
    // moduleId: module.id,
    selector: "tk-sidedrawer-getting-started",
    templateUrl: "./components/sidedrawer/sidedrawer.html",
    styleUrls: ['./components/sidedrawer/sidedrawer.css'],
    //providers: [BottomBarService]
})
export class SideDrawerGettingStartedComponent implements AfterViewInit, OnInit {
    private _mainContentText: string;

    constructor(private _changeDetectionRef: ChangeDetectorRef,private bottomBarService: BottomBarService) {
      this.bottomBarService.sideDrawerMethodCalled$.subscribe(() => {
        console.log("subscribed")
        alert("hello")
        this.openDrawer()
      })
    }

    @ViewChild(RadSideDrawerComponent) public drawerComponent: RadSideDrawerComponent;
    private drawer: RadSideDrawer;

    ngAfterViewInit() {
        this.drawer = this.drawerComponent.sideDrawer;
        this._changeDetectionRef.detectChanges();
    }

    ngOnInit() {
        this.mainContentText = "SideDrawer for NativeScript can be easily setup in the HTML definition of your page by defining tkDrawerContent and tkMainContent. The component has a default transition and position and also exposes notifications related to changes in its state. Swipe from left to open side drawer.";
    }

    get mainContentText() {
        return this._mainContentText;
    }

    set mainContentText(value: string) {
        this._mainContentText = value;
    }

    public openDrawer() {
        console.log("triggered openDrawer in main component")
        this.drawer.showDrawer();
    }

    public onCloseDrawerTap() {
       this.drawer.closeDrawer();
    }
}

And Shared service is as below

bottombar.service.ts

import { Subject }    from 'rxjs/Subject';
import { Injectable } from '@angular/core';

@Injectable()
export class BottomBarService{
    private sideDrawerMethodSource = new Subject<any>();
    sideDrawerMethodCalled$ = this.sideDrawerMethodSource.asObservable();

    callSideDrawerMethod(){
        console.log("Inside service bottomBar")
        this.sideDrawerMethodSource.next(null);
        console.log("after")
    }
}

Problem

I have an html associated with bottombar.component.ts which contains a button. On tap it will trigger openDrawer() function in bottombar.component.ts

I can see the consoled value in my service file, but somehow it is not triggering the subscribe in sidedrawer.component.ts

There is no error and because of that it is difficult to find what is exactly causing the issue.

Also I have declared my service in ngModule's provider to avoid singleton issue.

Is there something that I'm missing here?

Thanks in advance


Solution

  • In your shared service, instead of passing null here this.sideDrawerMethodSource.next(null), you can pass a status:boolean. In your bottombar.service.ts -

    callSideDrawerMethod(status:boolean){
        this.sideDrawerMethodSource.next(status);
    }
    

    Now, in the bottombar.component.ts, pass a status when invoking the method -

    this.bottomBarService.callSideDrawerMethod(true);
    

    In your sidedrawer.component.ts, pass a status param -

      this.bottomBarService.sideDrawerMethodCalled$.subscribe((status) => {
            console.log("subscribed")
            alert("hello")
            this.openDrawer()
          })
    

    And instead of subscribing in the constructor, place the code in ngOnInit() life cycle hook.

    Hope this helps.