Я создал службу CRUD, которая выполняет вызовы к классическому API. Я использую объект поведения для обмена данными между всеми компонентами моего приложения. Проблема в том, что когда я выполняю грубые операции, данные не обновляются во всех компонентах в режиме реального времени. Данные будут обновлены, если я перейду к другим компонентам.
Я не понимаю, почему это не работает в реальном времени, и я не могу найти, откуда моя ошибка.
Если кто-нибудь может мне помочь, это было бы очень приятно:)
Я пытался вызвать функцию get Candidates (), которая обновляет хранилище данных с помощью функции next () в каждом ngOnInit () моих компонентов, но поведение такое же
GitHub репо: https://github.com/jbty/signalr-majority-vote/tree/master/signalR-majority-vote/ClientApp
API угловой сервис:
export class ApiCandidateService {
public candidatesList: Observable<Candidate[]>;
private baseUrl: string;
private _candidatesList: BehaviorSubject<Candidate[]>;
private dataStore: {
candidatesList: Candidate[];
};
private httpOptions: { headers: HttpHeaders } = {
headers: new HttpHeaders({
"Content-Types": "applications/json"
})
};
public constructor(private http: HttpClient) {
this.baseUrl = "api/Candidates";
this.dataStore = { candidatesList: [] };
this._candidatesList = <BehaviorSubject<Candidate[]>>new BehaviorSubject([]);
this.candidatesList = this._candidatesList.asObservable();
}
public getCandidates() {
this.http.get<Candidate[]>(this.baseUrl, this.httpOptions).subscribe(
(data: Candidate[]) => {
this.dataStore.candidatesList = data;
this._candidatesList.next(Object.assign({}, this.dataStore).candidatesList);
},
error => {
this.handleError(error);
}
);
}
public getCandidate(id: number | string) {
this.http.get<Candidate>(`${this.baseUrl}/${id}`, this.httpOptions).subscribe(
(data: Candidate) => {
let notFound = true;
this.dataStore.candidatesList.forEach((item, index) => {
if (item.candidateId == data.candidateId) {
this.dataStore.candidatesList[index] = data;
notFound = false;
}
});
if (notFound) {
this.dataStore.candidatesList.push(data);
}
this._candidatesList.next(Object.assign({}, this.dataStore).candidatesList);
},
error => {
this.handleError(error);
}
);
}
public createCandidate(newCandidate: Candidate) {
this.http.post<Candidate>(`${this.baseUrl}`, newCandidate, this.httpOptions).subscribe(
(data: Candidate) => {
this.dataStore.candidatesList.push(data);
this._candidatesList.next(Object.assign({}, this.dataStore).candidatesList);
},
error => {
this.handleError(error);
}
);
}
public updateCandidate(id: number | string, updatedCandidate: Candidate) {
this.http.put<Candidate>(`${this.baseUrl}/${id}`, updatedCandidate, this.httpOptions).subscribe(
() => {
this.dataStore.candidatesList.forEach((candidate, i) => {
if (candidate.candidateId == updatedCandidate.candidateId) {
this.dataStore.candidatesList[i] = updatedCandidate;
}
});
this._candidatesList.next(Object.assign({}, this.dataStore).candidatesList);
},
error => {
this.handleError(error);
}
);
}
public deleteCandidate(id: number | string) {
this.http.delete<Candidate>(`${this.baseUrl}/${id}`, this.httpOptions).subscribe(
response => {
this.dataStore.candidatesList.forEach((candidate, i) => {
if (candidate.candidateId == Number(id)) {
this.dataStore.candidatesList.splice(i, 1);
}
});
this._candidatesList.next(Object.assign({}, this.dataStore).candidatesList);
},
error => {
this.handleError(error);
}
);
}
private handleError(error: HttpErrorResponse) {
if (error.error instanceof ErrorEvent) {
// A client-side or network error occurred. Handle it accordingly.
console.error("An error occurred:", error.error.message);
} else {
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong,
console.error(`Backend returned code ${error.status}, ` + `body was: ${error.error}`);
}
// return an observable with a user-facing error message
return throwError("Something bad happened; please try again later.");
}
}
пример компонента
export class DeleteCandidatesComponent implements OnInit {
public candidate: Observable<Candidate>;
public candidateId: string;
constructor(
public nav: NavigationService,
private route: ActivatedRoute,
private candidateService: ApiCandidateService
) {
this.candidateId = this.route.snapshot.params.id;
}
public ngOnInit(): void {
this.candidate = this.candidateService.candidatesList.pipe(
map(candidate => candidate.find(item => item.candidateId == Number(this.candidateId)))
);
this.candidateService.getCandidate(this.candidateId);
}
public onDefinitivlyDeleteCandidate(id: string) {
this.candidateService.deleteCandidate(id);
this.nav.outletsNav('classement', 'manage/candidates')
}
}
мой взгляд
<header>
<h2>
êtes vous sûr de vouloir supprimer définitvement
<strong>{{ (candidate | async)?.firstName }} {{ (candidate | async)?.lastName }}</strong> ?
</h2>
</header>
<aside class="submit">
<button mat-button color="primary" (click)="onDefinitivlyDeleteCandidate(candidateId)">
Oui
</button>
<button mat-button color="warn" (click)="nav.outletsNav('classement', 'manage/candidates')">
annuler
</button>
</aside>