У меня есть ApiService, который предназначен для отправки запросов на сервер отдыха. Он используется несколькими ComponentServices для восстановления и отправки данных с / на сервер
Например: UsernewComponent & UserlistComponent используют userService, который использует apiService.
Я хотел бы передавать ошибки от служб к конечным компонентам чтобы иметь возможность показывать модал или что-то еще при возникновении ошибки.
Но мне это не удается ...
Спасибо за вашу помощь! NB: поскольку я новичок в Angular & Rx js, если вы видите что-то в моем коде, что может быть лучше, пожалуйста, сообщите мне; -)
api.service.ts
import { Injectable } from '@angular/core';
import { HttpClient, HttpErrorResponse } from '@angular/common/http';
import { throwError } from 'rxjs';
import { map, catchError, timeout } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class ApiService {
private baseEndpoint = 'http://myurl/projserver/api/';
private maxTime = 5000;
constructor(private httpClient: HttpClient) { }
public getEntriesFromRest (option: string): any {
return this.httpClient.get<any[]>(this.baseEndpoint + option)
.pipe(
timeout(this.maxTime),
catchError(this.handleError),
map((data) => data['hydra:member'])
);
}
public getEntryFromRest (option: string): any {
return this.httpClient.get<any>(this.baseEndpoint + option)
.pipe(
timeout(this.maxTime),
catchError(this.handleError)
);
}
handleError(error: HttpErrorResponse) {
let errorMessage = 'Unknown error!';
if (error.error instanceof ErrorEvent) {
// Client-side errors
errorMessage = `Error: ${error.error.message}`;
} else {
// Server-side errors
errorMessage = `Error Code: ${error.status}\nMessage: ${error.message}`;
}
return throwError(errorMessage);
}
}
user.service.ts
import { User } from '../models/User.model';
import { Injectable } from '@angular/core';
import { Subject } from 'rxjs/Subject';
import { ApiService } from './api.service';
import { throwError } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class UserService {
private users: User[] = [];
private usersSubject = new Subject<User[]>();
usersSubject$ = this.usersSubject.asObservable();
private user: User;
private userSubject = new Subject<User>();
userSubject$ = this.userSubject.asObservable();
constructor(private apiService: ApiService) { }
emitUsers() {
this.usersSubject.next(this.users.slice());
}
emitUser() {
this.userSubject.next(this.user);
}
addUser(user: User) {
this.users.push(user);
this.emitUsers();
}
editUser(user: User) {
var index = this.users.findIndex((item) => item.id === user.id);
this.users.splice(index, 1, user);
this.emitUsers();
}
getUsersFromRest() {
this.users=[];
this.apiService.getEntriesFromRest('users').subscribe(
(data: any[]) => { data.forEach( (item: User) => {
this.users.push(item);});
this.emitUsers();
},
(error) => {
console.log('UserService: '+error);
this.userSubject.next(error);
return throwError(error);
});
}
getUserFromRest(userId: number) {
this.apiService.getEntryFromRest('users/'+userId).subscribe(
(data: User) => {
this.user=data;
this.emitUser();
},
(error) => {
console.log('UserService: '+error);
this.userSubject.next(error);
return throwError(error);
}
);
}
}
usernew.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { FormBuilder, FormGroup, Validators, FormArray, FormControl } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';
import { Subscription } from 'rxjs/Subscription';
import { User } from '../../../models/User.model';
import { Role } from '../../../models/Role.model';
import { UserService } from '../../../services/user.service';
import { MustMatch } from '../../../validators/must-match.validator';
import { NbDialogService } from '@nebular/theme';
import { DialogComponent } from '../../../components/dialog/dialog.component';
@Component({
selector: 'usernew',
templateUrl: './usernew.component.html',
styleUrls: ['./usernew.component.scss']
})
export class UsernewComponent implements OnInit, OnDestroy {
userIdSubscription: Subscription;
userSubscription: Subscription;
user: User;
...
constructor(private formBuilder: FormBuilder,
private userService: UserService,
private router: Router,
private route: ActivatedRoute,
private nbDialogService: NbDialogService
) { }
ngOnInit() {
this.initForm();
this.userSubscription = this.userService.userSubject$.subscribe(
(user: User) => {
if (user) {
this.user = user;
this.editUser(this.user);
}
},
(error) => {
console.log('Component: '+error);
}
);
this.userIdSubscription = this.route.paramMap.subscribe(params => {
const userId = +params.get('id'); //cast to number
if(userId) {
this.view='Edit';
this.loading = true;
this.userService.getUserFromRest(userId);
}
});
}
ngOnDestroy() {
this.userIdSubscription.unsubscribe();
this.userSubscription.unsubscribe();
}
...
}
userlist.component.ts
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Subscription } from 'rxjs/Subscription';
import { Router, ActivatedRoute } from '@angular/router';
import { User } from '../../../models/User.model';
import { UserService } from '../../../services/user.service';
@Component({
selector: 'userlist',
templateUrl: './userlist.component.html',
styleUrls: ['./userlist.component.scss']
})
export class UserlistComponent implements OnInit, OnDestroy {
...
users: User[] = [];
usersSubscription: Subscription;
loading = false;
constructor(
private userService: UserService,
private router: Router,
private route: ActivatedRoute,
) { }
ngOnInit() {
this.usersSubscription = this.userService.usersSubject$.subscribe(
(users: User[]) => {
this.users = users;
this.loading = false;
},
(error) => {
console.log("Userlist Component: "+error);
}
);
this.loading = true;
this.userService.getUsersFromRest();
//this.userService.emitUsers();
}
ngOnDestroy() {
this.usersSubscription.unsubscribe();
}
...
}