简体   繁体   中英

Angular Observable returns no data

I am trying to pass the data from one component to another component which are unrelated using service.

I am trying the solution from here https://www.intersysconsulting.com/blog/angular-components/ .

My service class is

import { Subject, Observable } from 'rxjs';
import { Domain } from '../model/domain.model';
import { Project } from '../model/project.model';
import { Injectable } from '@angular/core';

@Injectable()
export class DomainProjectService{
private domain = new Subject<Domain[]>();
private project = new Subject<Project[]>();

getProject() : Observable<Project[]>{
    return this.project.asObservable();
}

getDomain() : Observable<Domain[]>{
    return this.domain.asObservable();
}

updateProject(proj : Project[]){
    this.project.next(proj);
}

updateDomain(dom : Domain[]){
    this.domain.next(dom);
}
}

My source component

import { Component, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Project } from '../../model/project.model';
import { Domain } from '../../model/domain.model';
import { DomainProjectService } from 'src/app/services/domain-project.service';

@Component({
  selector: 'app-status-update',
  templateUrl: './status-update.component.html',
  styleUrls: ['./status-update.component.css']
})
export class StatusUpdateComponent implements OnInit {
  project : Project[] = [];
  domain_main : Domain[] = [];

  constructor(private http: HttpClient,  
    private modalService: NgbModal, 
    private domainProjectService: DomainProjectService) { }

  ngOnInit() {
    this.fetchProject();
    this.fetchDomain();
  }

  openFormModal() {
    const modalRef = this.modalService.open(FormModalComponent);
    modalRef.componentInstance.id = 10; // should be the id
    modalRef.result.then((result) => {
      console.log("result is"+ JSON.stringify(result));
      this.http
      .post<{ name: string }>(
        'http://localhost:8080/statusupdate',
        JSON.stringify(result), 
        {
         headers : new HttpHeaders().set('Content-Type', 'application/json')
        }

      )
      .subscribe(responseData => {
        console.log(responseData);
        this.fetchStatus();
      });

    }).catch((error) => {
      console.log(error);
    });
  }


  private fetchProject()
  {
    this.http
    .get<Project[] >(
      'http://localhost:8080/projects'
    ).subscribe(posts => {
      this.project = posts;
      console.log(this.project);//I get values here
      this.domainProjectService.updateProject(this.project);
    });
  }

  private fetchDomain()
  {
    this.http
    .get<Domain[] >(
      'http://localhost:8080/domains'
    ).subscribe(posts => {
      this.domain_main = posts;
      console.log(this.domain_main);//I get values here
      this.domainProjectService.updateDomain(this.domain_main);
    });
  }

My target component

import { Component, OnInit, Input } from '@angular/core';
import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
import { FormGroup, FormBuilder } from '@angular/forms';
import { Project } from 'src/app/model/project.model';
import { Domain } from 'src/app/model/domain.model';
import { DomainProjectService } from 'src/app/services/domain-project.service';
import { Subscription } from 'rxjs';


@Component({
  selector: 'app-form-modal',
  templateUrl: './form-modal.component.html',
  styleUrls: ['./form-modal.component.css']
})
export class FormModalComponent implements OnInit {

  @Input() id: number;
  myForm: FormGroup;

  project : Project[] = [];
  domain_main : Domain[] = [];
  proj = new Subscription();
  dom = new Subscription();

  constructor(  public activeModal: NgbActiveModal, 
                private formBuilder: FormBuilder, 
                private domainProjectService: DomainProjectService ) {
    this.createForm();

    this.proj = this.domainProjectService.getProject().subscribe(abc=>
  {
      this.project=abc;
      console.log(this.project);// returns empty array 
  }); 
    this.dom = this.domainProjectService.getDomain().subscribe(abc=>this.domain_main=abc);
    console.log(this.domain);// returns empty array
   }

   ngOnDestroy(){
     this.proj.unsubscribe();
     this.dom.unsubscribe();
   }

  ngOnInit() {

  }
  private createForm() {
    this.myForm = this.formBuilder.group({
      project_id: '',
      domain_id: '',
      status:''
    });
  }
  private submitForm() {
    this.activeModal.close(this.myForm.value);
    console.log(this.myForm.value);
  }
  closeModal() {
    this.activeModal.close('Modal Closed');
  }
  public onChange(event): void {  
    const newVal = event.target.value;
    console.log(newVal);
    console.log(this.domain);
  }
}

HTML file of my target component

    <div class="modal-header">
    <h6 class="modal-title">Update your status</h6>
    <button type="button" class="close" aria-label="Close"
    (click)="activeModal.dismiss('Cross click')">x
    </button>
</div>
<form [formGroup]="myForm" (ngSubmit)="submitForm()">
    <div class="modal-boy">
    <div class="container">
        <div class="form-group">
        <label>Project</label>
            <select class="form-control form-control-sm" formControlName="project_id" (change)="onChange($event)">
                <option value="">-- please choose the project --</option>
            <option *ngFor="let v of project" [value]="v.id">{{v.project}}</option>
        </select>
        </div>
        <div class="form-group">
            <label>Domain</label>
            <select class="form-control form-control-sm" formControlName="domain_id">
                <option value="">-- please choose the domain --</option>
            <option *ngFor="let v of domain" [value]="v.id">{{v.domain}}</option>
            </select>
        </div>
        <div class="form-group">
            <label>Status</label>
            <textarea type="text" 
            class="form-control"
            formControlName="status"></textarea>
        </div>
    </div>
    </div>
    <div class="modal-footer">
    <button class="btn btn-success btn-sm"
        [disabled]="!myForm.valid">
        Add
    </button>
    </div>
</form>

形成

But I receive no data at my target component, though I have my data exactly at my source. Kindly advice what I am missing here. Thanks in advance.

@Eldryc is correct. You are trying to log something which didn't get its value yet. this.domainProjectService.getProject().subscribe(abc=> { this.project=abc; console.log(this.project); });

Try the above

I found the mistake. BehaviourSubject() instead of Subject() in service worked.

import { BehaviourSubject, Observable } from 'rxjs';
import { Domain } from '../model/domain.model';
import { Project } from '../model/project.model';
import { Injectable } from '@angular/core';

@Injectable()
export class DomainProjectService{
private domain = new BehaviourSubject<Domain[]>(null);
private project = new BehaviourSubject<Project[]>(null);

getProject() : Observable<Project[]>{
    return this.project.asObservable();
}

getDomain() : Observable<Domain[]>{
    return this.domain.asObservable();
}

updateProject(proj : Project[]){
    this.project.next(proj);
}

updateDomain(dom : Domain[]){
    this.domain.next(dom);
}
}

Please find the this What is the difference between Subject and BehaviorSubject? link for reference

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM