user15041100
user15041100

Reputation:

Why subscription not working in constructor?

I have the following class:

I try to save prev and current state, and replace preve state on current by user click.

@Injectable({
  providedIn: "root",
})
export class PortalBridgeService {
  private portalsSubject = new Subject<Portal>();
  private prev: Portal;

  readonly portals$ = this.portalsSubject.pipe(
    startWith(portalDefault()),
    pairwise(),
    map(([prev, current]) => ({ prev, current }))
  );
  // States
  readonly currentPortal$ = this.portals$.map((value) => value.current);
  readonly prevPortal$ = this.portals$.map((value) => value.prev);

  constructor() {
    this.prevPortal$.subscribe((prev) => (this.prev = prev));
  }

  activatePortal(type: PortalType) {
    try {
      const portal = portalByType(type);

      if (!portal) throw `There is not found portal with type ${type}`;

      this.setPortal(portal);
    } catch (e) {
      console.error(e);
    }
  }

  setPortal(portal: Portal) {
    this.portalsSubject.next(portal);
  }

  disposePortal() {
    if (this.prev) {
      this.setPortal(this.prev);
    }
  }
}

Template is:

<ng-template [cdkPortalOutlet]="currentPortal$ | async"></ng-template>

Why I dont get value in this.currentPortal$.subscribe((res) => console.log(res)); despite startWith emits first value?

I use async in template:

currentPortal$ | async

I tried to simplify this to:

export class PortalBridgeService implements OnInit {
  public portalsSubject = new BehaviorSubject<Portal>(portalDefault());

  ngOnInit() {
    this.portalsSubject
      .pipe(
        pairwise(),
        map(([prev, current]) => ({ prev, current }))
      )
      .subscribe((data) => console.log(data));
  }
}

.subscribe((data) => console.log(data)); not working!

Upvotes: 0

Views: 830

Answers (2)

BizzyBob
BizzyBob

Reputation: 14740

This code is not correct, is typescript giving you any errors?

readonly prevPortal$ = this.portals$.map((value) => value.prev);

I think you want:

readonly prevPortal$ = this.portals$.pipe(map(v => v.prev));

Upvotes: 1

JeffryHouser
JeffryHouser

Reputation: 39408

Pipe Operators will never force the Observable to emit a value. At some point you'll have to call next() to start the process

export class PortalBridgeService {
  constructor() {
    this.currentPortal$.subscribe((res) => console.log(res));
    this.portalsSubject.next(); // <---- do this here
  }
}

Upvotes: 0

Related Questions