Welcome toVigges Developer Community-Open, Learning,Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.4k views
in Technique[技术] by (71.8m points)

rxjs - Angular : Subject is not updating the component

Subject is not updating the component. I have 2 components c1 and c2 and a service class CommonService

C1 component having code related to post data.

export class C1Component implements OnInit {
  dBservice: CommonService
  constructor(private service: CommonService) { 
    this.dBservice = service
  }
  ngOnInit(): void {
    
  }
  getData(event, val) {
    event.preventDefault();
    this.SendDataToServer(val)
  }

  SendDataToServer(value) {
    this.dBservice.postData(value).subscribe(data => {
      console.log(data)
    }, err => {
        console.log(err)
    })
  }

C2 component having code related to get data from API server.

  dBservice: CommonService
  data: []
  constructor(private service: CommonService) { 
    this.dBservice = service
  }

  ngOnInit(): void {
    console.log("coming")
    this.dBservice._updates.subscribe((data) => {
      console.log("c")
      this.dBservice.getAll().subscribe(data => console.log(this.data=data))
    })
    this.dBservice.getAll().subscribe(data => console.log(this.data=data))
  }

}

My C2 component is not updating automatically without page refresh, when C1 component inserts the data using POST call.

My Service File

@Injectable({
  providedIn: 'root'
})
export class CommonService {
  updates : any;
  constructor(private http: HttpClient) {
    this.updates = new Subject<string>();
   }
  
  get _updates() {
    return this.updates;
  }
  postData(value) {
    const httpOptions = {
      headers: new HttpHeaders({
        'Content-Type':  'application/json',
        Authorization: 'my-auth-token'
      })
    };
    var url = "http://localhost:3000/Todos"
    return this.http.post<{ "todo": string }>(url, {
      "id" : uuid.v4(),
      "todo" : value
    }, httpOptions).pipe(
      tap(() => {
        this.updates.next()
      })
    )
  }

  getAll() {
    var url = "http://localhost:3000/Todos"
    return this.http.get<[]>(url)
  }
}

Templates Template: C1

<form>
  <input type="text" #name />
  <input type="submit" (click)="getData($event, name.value)" />
</form>

Template of C2:

<div *ngFor="let n of data">
  {{ n.todo }}
</div>

Note: With refresh, the data is getting populated, but without refresh it is not working.

question from:https://stackoverflow.com/questions/65861475/angular-subject-is-not-updating-the-component

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

Here is a simplified example that does a very similar job without a real backend. It demonstrates the use of BehaviorSubject and how one component updates and the other listens and reacts in real time (full working example here).

Service

import { Injectable } from "@angular/core";
import { BehaviorSubject } from "rxjs";

@Injectable()
export class DataService {
  updates$ = new BehaviorSubject<string[]>([]);

  constructor() {}

  postData(value: string): void {
    this.updates$.value.push(value);
    this.updates$.next([...this.updates$.value]);
  }
}

Component 1 (the posting component):

HTML

<form>
  <input type="text" #name>
  <input type="submit" value="Post" (click)="submit($event, name.value)">
</form>

TS

import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';

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

  constructor(private dataService: DataService) { }

  ngOnInit() {
  }

  submit(event: Event, value: string): void {
    event.preventDefault();
    this.dataService.postData(value);
  }
}

Component 2 (the listener)

HTML

<ul>
  <li *ngFor="let value of updates">{{ value }}</li>
</ul>

TS

import { Component, OnInit } from '@angular/core';
import { DataService } from '../data.service';

@Component({
  selector: 'app-listing',
  templateUrl: './listing.component.html',
  styleUrls: ['./listing.component.css']
})
export class ListingComponent implements OnInit {
  updates: string[] = [];

  constructor(private dataService: DataService) { }

  ngOnInit() {
    this.dataService.updates$.subscribe(updates => this.updates = [...updates]);
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to Vigges Developer Community for programmer and developer-Open, Learning and Share
...