Always_a_learner
Always_a_learner

Reputation: 5055

Observable do not receive event when next is called by subject

service.ts:

  private showBoxAction = new Subject<any>();
  showBox = this.showBoxAction.asObservable();
  openBox() {
    console.log("in Box");

    this.showBoxAction.next(true);
  }

Component1.html

 <ng-template #noMsgs>
                  <div id="top" class="container">
                    <div class="row">
                      <div class="col-xs-12 explorer-results">
                        <div class="no-results-found">
                          <div class="joinUs">
                                <span>
                                  <p >Join us.</p>
                                  <a href="javascript:" (click)="showBox()" class="mat-button default">Start Now</a>
                                </span>
                            </div>
                        </div>
                      </div>
                    </div>
                  </div>
                </ng-template>

component1.ts

      providers: [, DatePipe, FragmentParamsPipe],
import { environment } from "./../../../../environments/environment";
import { Http, ConnectionBackend } from "@angular/http";
import {
  Component,
  OnInit,
  OnDestroy,
  AfterViewInit,
  HostListener,
  Inject,
  NgZone,
  ViewChild,
  ElementRef,
  Output
} from "@angular/core";
import { DOCUMENT, Title } from "@angular/platform-browser";


import { Subscription } from "rxjs/Subscription";
import {
  CONSTANT,
  FEATURE,
  flattenJSON,
  unflattenJSON
} from "../../../Constants";
import { Observable } from "rxjs/Observable";
import { MatDialog, MatDialogRef } from "@angular/material";
import { BehaviorSubject } from "rxjs/BehaviorSubject";
import { Subject } from "rxjs/Subject";
import { Router, NavigationEnd, ActivatedRoute } from "@angular/router";
import { TabsetComponent } from "ngx-bootstrap";
import { Service } from "/src/app/services/service";
import { FragmentParamsPipe } from "../../../pipes/url/fragment-params.pipe";

declare let jQuery: any;
@Component({
  selector: "component1",
  templateUrl: "./component1.component.html",
  styleUrls: ["./component1.component.css"],
  providers: [QuestionControlService, DatePipe, FragmentParamsPipe],
  entryComponents: [DialogBoxComponent, MasterListComponent]
})
export class UserProfileComponent implements OnInit, OnDestroy, AfterViewInit {

  constructor(
    @Inject(DOCUMENT) private document: Document,
    private _service: Service,

  ) {


  }

  ngOnInit() {

  }


  /**
   * Display messageBox component.
   */
  showBox() {
      this._service.openComposeBox();
  }

  ngAfterViewInit() {

  }



  ngOnDestroy(): void {
  }




  }

Component2.ts

 private subscriptions = new Subscription();

  constructor(private _service:Service)
{

    this.subscriptions.add(
      this._service.showBox.subscribe(event => {
        if (event) {

        console.log("display box");
        }
      })
    );
}

When I click on show-box to trigger showBox() function I get output in console "in Box" but I do not get console "display box" i.e observable is not subscribed. What could be the reason where as when my next trigger calls openBox() then observable subscribes successfully. What is wrong with my implementation?

UPDATE

Problem is only when I call it through component1.ts and it is first time in app when I use it. I have tried subscribing without adding it into subscription.

component2.ts

 ngOnInit() {
    this._service.showBox.takeUntil(this.destroy$).subscribe(event => {

      if (event) {
        this.displayCompose = true;
        console.log("display box");
      }
    })

  }



 ngOnDestroy(): void {

    this.destroy$.next(true);
    // Now let's also unsubscribe from the subject itself:
    this.destroy$.unsubscribe();

    this.subscriptions.unsubscribe();
  }
}

UPDATE

Structure of my app and components I have referred in post: my-angular-app\src\app\components\component1\componen1.ts

my-angular-app\node_modules\angular-app2\components\component2-parent\component2-parent.ts

my-angular-app\node_modules\angular-app2\components\component2\component2.ts Component1.component.html:

     <ng-template #noMsgs>
                      <div id="top" class="container">
                        <div class="row">
                          <div class="col-xs-12 explorer-results">
                            <div class="no-results-found">
                              <div class="joinUs">
                                    <span>
                                      <p >Join us.</p>
                                      <a href="javascript:" (click)="showBox()" class="mat-button default">Start Now</a>
                                    </span>
                                </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </ng-template>

<component2-parent *ngIf="display"></component2-parent>

component1.ts

export class Component1 
showBox()
{
this.display = true;
_service.openBox()
}

component2-parent contains component2.

Upvotes: 0

Views: 2054

Answers (2)

user6749601
user6749601

Reputation:

Okay, let‘s try it another way.

Instead of this line of code in your service.ts

showBox = this.showBoxAction.asObservable();

put this method

getShowBoxAction(): Observable<any> {
   return this.showBoxAction.asObservable();
}

And in your component2.ts subscribe this way

// of course you can add this to your subscriptions-object as well.
this._service.getShowBoxAction().subscribe( event => {

    // the rest of your code

});

Edit: 15. July 2018 1.29 pm

You do not call the right service. This is what you currently call in component1:

// **
   * Display messageBox component.
   */
    showBox() {
        this._mailingService.openComposeBox();
    }

But you have to call your service.ts!

showBox() {
    this._service.openBox();
}

Please replace the code any give it a try.

Upvotes: 0

Amit Chigadani
Amit Chigadani

Reputation: 29715

Use BahaviourSubject, so that you do not miss out the initial value,

private showBoxAction = new BehaviorSubject <any>();

and also add your subscription inside ngOnInit() (good practice) as opposed to constructor.

ngOnInit() {
  this._service.showBox.subscribe(event => {
    if (event) {
      this.displayCompose = true;

    console.log("display box");
    }
  })

Upvotes: 2

Related Questions