Rxjs subscribe method being ignored

梦想的初衷 提交于 2019-12-02 16:45:22

问题


BEFORE tagging it as a duplicate, note that None of these worked for me: question 1 / question 2 / question 3

So, after getting a reply to a previous question I started using rxjs following everything stated on the guide I was provided with

However, I soon got stuck again for the last couple of hours because of the subscribe method not being triggered.

I've coded my service like:

import { Injectable } from '@angular/core';
import { Subject }    from 'rxjs/Subject';
import {FormDTO} from "../dto/formDTO.model";

@Injectable()
export class ApiDosageDialogFormCommunicationService {

    private formDTO = new Subject<FormDTO>();

    //Observable string streams
    formDTOpulling$ = this.formDTO.asObservable();

    //Service message commands
    formDTOpushing(formDTO: FormDTO) {
        this.formDTO.next(formDTO);
    }

Sending it from the parent to the child like:

this.apiDosageDialogFormCommunicationService.formDTOpushing(this.formDTO)

It works fine up until here, the service receives the DTO and I can read its values, but when I try to use it in the modal service, the subscribe method does nothing at all, this is the component in which I'm trying to fetch the DTO:

  import {Component, OnDestroy, OnInit} from "@angular/core";
import {JhiEventManager} from "ng-jhipster";
import {NgbActiveModal} from "@ng-bootstrap/ng-bootstrap";
import {Response} from "@angular/http";
import {ActivatedRoute} from "@angular/router";
import {Observable} from "rxjs/Rx";
import {FormService} from "./form.service";
import {FormDTO} from "../dto/formDTO.model";
import {ApiDosageDialogFirstStepPopupService} from "./apiDosage-dialog-first-step-popup.service";
import {ApiDosageDialogFormCommunicationService} from "./apiDosageDialogFormCommunication.service";
import {Subscription} from "rxjs/Subscription";

@Component({
    selector: 'jhi-apiDosage-dialog-first-step',
    templateUrl: './apiDosage-dialog-first-step.component.html'
})

export class ApiDosageDialogFirstStepComponent implements OnInit {

    formDTO: FormDTO;
    isSaving: boolean;

    constructor(
        public activeModal: NgbActiveModal,
        private formService: FormService,
        private apiDosageDialogFormCommunicationService: ApiDosageDialogFormCommunicationService,
        private eventManager: JhiEventManager
    ) {
    }

    ngOnInit() {
        this.isSaving = false;
    }

    clear() {
        this.activeModal.dismiss('cancel');
    }

    save() {
        this.isSaving = true;
        if (this.formDTO.id !== undefined) {
            this.subscribeToSaveResponse(
                this.formService.save(this.formDTO));
        } else {
            this.subscribeToSaveResponse(
                this.formService.save(this.formDTO));
        }
    }

    private subscribeToSaveResponse(result: Observable<FormDTO>) {
        result.subscribe((res: FormDTO) =>
            this.onSaveSuccess(res), (res: Response) => this.onSaveError());
    }

    private onSaveSuccess(result: FormDTO) {
        this.eventManager.broadcast({ name: 'journalListModification', content: 'OK'});
        this.isSaving = false;
        this.activeModal.dismiss(result);
    }

    private onSaveError() {
        this.isSaving = false;
    }
}

@Component({
    selector: 'jhi-apiDosage-first-step-popup',
    template: ''
})
export class ApiDosageDialogFirstStepPopupComponent implements OnInit, OnDestroy {

    routeSub: any;
    formDTO: any;
    subscription: Subscription;

    constructor(
        private route: ActivatedRoute,
        private apiDosagePopupService: ApiDosageDialogFirstStepPopupService,
        private apiDosageDialogFormCommunicationService: ApiDosageDialogFormCommunicationService
    ) {

    }

    ngOnInit() {
        this.subscription = this.apiDosageDialogFormCommunicationService.formDTOpulling$.subscribe(
            formDTO => {
                 console.log('In the component' +this.formDTO.sample.id),
                 this.formDTO = formDTO;
             },
             error => {
                 alert('Made it all the way here: '+this.formDTO);
             });
        this.routeSub = this.route.params.subscribe((params) => {
            this.apiDosagePopupService
                    .open(ApiDosageDialogFirstStepComponent as Component, this.formDTO);
        });
    }

    ngOnDestroy() {
        this.routeSub.unsubscribe();
    }
}

Please note that in the previous class, I've tried adding the subscribe method in both onInit and in the constructors.

The previous class calls open method of the modal, being this the source code for the modal's service:

import { Injectable, Component } from '@angular/core';
import { Router } from '@angular/router';
import { NgbModal, NgbModalRef } from '@ng-bootstrap/ng-bootstrap';
import {FormService} from "./form.service";
import {FormDTO} from "../dto/formDTO.model";
import {Observable} from "rxjs/Observable";

@Injectable()
export class ApiDosageDialogFirstStepPopupService {
    private ngbModalRef: NgbModalRef;

    constructor(
        private modalService: NgbModal,
        private router: Router,
        private formService: FormService

    ) {
        this.ngbModalRef = null;
    }

    open(component: Component, formDTO?: Observable<any> | any): Promise<NgbModalRef> {
        return new Promise<NgbModalRef>((resolve, reject) => {
            const isOpen = this.ngbModalRef !== null;
            if (isOpen) {
                resolve(this.ngbModalRef);
            }
            if (formDTO) {
                  // this.formService.find(id).subscribe((journal) => {
                  //     this.ngbModalRef = this.journalModalRef(component, journal);
                  //     resolve(this.ngbModalRef);
                  // });
                setTimeout(() => {
                    this.ngbModalRef = this.apiDosageFirstStepModalRef(component, formDTO);
                         resolve(this.ngbModalRef);
                         console.log(formDTO);
                }, 0);
                } else {
                 //setTimeout used as a workaround for getting ExpressionChangedAfterItHasBeenCheckedError
                 setTimeout(() => {
                     this.ngbModalRef = this.apiDosageFirstStepModalRef(component, new Observable<any>());
                     resolve(this.ngbModalRef);
                 }, 0);
                alert('no form');
            }
        });
    }

    apiDosageFirstStepModalRef(component: Component, formDTO: Observable<any>): NgbModalRef {
        const modalRef = this.modalService.open(component, { size: 'lg', backdrop: 'static'});
        modalRef.componentInstance.formDTO = formDTO;
        modalRef.result.then((result) => {
            this.router.navigate([{ outlets: { popup: null }}], { replaceUrl: true, queryParamsHandling: 'merge' });
            this.ngbModalRef = null;
        }, (reason) => {
            this.router.navigate([{ outlets: { popup: null }}], { replaceUrl: true, queryParamsHandling: 'merge' });
            this.ngbModalRef = null;
        });
        return modalRef;
    }
}

回答1:


What is happening is formDTOpushing is being called before the components subscribe. This means the components will not receive that value. Components that subscribe to a Subject only receive values that are emitted after they subscribe. (They do not receive a value when they initially subscribe)

To have the the components receive previous emitted value(s) on subscribe, use a BehaviorSubject or ReplaySubject instead



来源:https://stackoverflow.com/questions/48328361/rxjs-subscribe-method-being-ignored

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!