Я работаю с angular только несколько месяцев и в настоящее время перегружен услугами.Я использую 3 угловых сервиса, которые взаимодействуют друг с другом.AuthService, configService и guardService.
В моем guardService метод checkBusinessCase (bcase) проверяет текущий бизнес-случай и устанавливает его с помощью метода this.authService.setActiveBusinessCase (bcase) внутри моего AuthService.
GuardService выглядит следующим образом:
import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
import { Observable, of } from 'rxjs';
import { UserAuthService } from './user-auth.service';
import { Constants } from '../../constants';
import { catchError, map } from 'rxjs/operators';
@Injectable()
export class BcaseRequiredGuard implements CanActivate {
constructor(private router: Router,
private authService: UserAuthService) {
}
canActivate(next: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<boolean> | Promise<boolean> | boolean {
if (next.data['bcase']) {
return this.checkBusinessCase(next.data['bcase']);
}
if (next.data['bcaseRegExp']) {
return this.checkBusinessCase(new RegExp(next.data['bcaseRegExp']));
}
this.router.navigate([Constants.routing.error, 'invalidBusinessCase']);
return false;
}
checkBusinessCase(bcase): Observable<boolean> {
return this.authService.isLoggedIn().pipe(
map(isLoggedIn => {
const accept = isLoggedIn && this.authService.hasBusinessCase(bcase);
if (accept) {
console.log('This guard approved that the Business case ' + bcase + ' is assigned to ' + this.authService.user.user_name);
this.authService.setActiveBusinessCase(bcase);
} else {
console.log('This guard approved that the Business case ' + bcase + ' is not assigned to ' + this.authService.user.user_name);
this.router.navigate([Constants.routing.home]);
}
return accept;
}),
catchError((err) => {
console.error(Constants.errors.loginCheckFailed, err);
this.router.navigate([Constants.routing.error, 'loginCheckFailed']);
return of(false);
}));
}
}
Именно этот бизнес-пример мне нужен в моем configService в методе getAutoConfiguredBCLanguage () .Когда я пытаюсь получить к нему доступ с помощью this.authService.activeBusinessCase , я получаю неопределенное значение, потому что configService вызывается перед authService.
configService выглядит следующим образом:
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import 'moment/locale/de';
import { UserAuthService } from 'app/auth/user-auth.service';
@Injectable()
export class ConfigurationService {
defaultLanguage = 'en';
activeBusinessCase = '';
languages = {
en: 'English',
de: 'German',
es: 'Spanish',
ja: 'Japanese',
pt: 'Portuguese'
};
// Business cases with available translation files
businessCases = {
case1: '_case1',
case2: '_case2',
case3: '_case3'
};
constructor(
private translate: TranslateService,
private authService: UserAuthService
) {
}
// Get business case specific language
// TODO: Get currently logged in business case
getAutoConfiguredBCLanguage(){
const browserLang = this.translate.getBrowserLang();
console.log('BROWSER LANGUAGE: ', browserLang);
console.log('ACTIVE BUSINESS CASE: ', this.activeBusinessCase);
if (this.languages.hasOwnProperty(browserLang) && this.activeBusinessCase !== undefined) {
switch (this.activeBusinessCase) {
case 'CASE1':
return browserLang.concat(this.businessCases.case1);
case 'CASE2':
return browserLang.concat(this.businessCases.case2);
case 'CASE3':
return browserLang.concat(this.businessCases.case2);
default:
return browserLang;
}
} else if (this.languages.hasOwnProperty(browserLang) && this.activeBusinessCase === undefined) {
console.log('No currently active business case.');
return browserLang;
} else {
return this.defaultLanguage;
}
}
}
И это authService, где установлено свойство activeBusinessCase, значение которого мне нужно:
import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { Constants } from '../../constants';
import { EMPTY, Observable } from 'rxjs';
import { PathLocationStrategy } from '@angular/common';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { translate } from '../shared/translation-util';
import { environment } from '../../environments/environment';
import { LoginError } from '../model/auth/LoginError';
import { User } from '../model/auth/User';
import { UiInfo } from '../model/auth/UiInfo';
import { ChangePasswordError } from '../model/auth/ChangePasswordError';
import { Title } from '@angular/platform-browser';
import { catchError, map, mergeMap, publishReplay, refCount, tap } from 'rxjs/operators';
import { LoginResponse } from '../model/auth/LoginResponse';
@Injectable()
export class UserAuthService {
activeBusinessCase: string;
constructor(private router: Router,
private httpClient: HttpClient,
private pls: PathLocationStrategy,
private titleService: Title) {
}
setActiveBusinessCase(bcase: string) {
this.activeBusinessCase = bcase;
this.setTitle(bcase);
}
}
Как я могуполучить текущее экономическое обоснование (activeBusinessCase) в моем configService?
ОБНОВЛЕНИЕ:
После принятия изменений fridoo и подгоняя их под мои нужды, теперь все выглядит более логично.Но теперь у меня есть сообщения об ошибках в другом месте, которые я не могу обработать.Вот прерывистые строки кода и сообщений об ошибках в консоли.
В моем http.service.ts:
getResource(key: string, lang: string): Observable<any> {
const headers = new HttpHeaders({'Accept': 'text/html'});
return this.httpClient.get('/resources/' + key,
{
headers: headers,
responseType: 'text',
params: new HttpParams()
.set('businessCase', this.authService.activeBusinessCase ? this.authService.activeBusinessCase :
environment.default_business_case)
.set('lang', lang)
}).pipe(
catchError(() => {
return this.translateService.get('Not-available').pipe(
map(res => '<h4 style="text-align: center">' + res + '</h4>'));
})
);
}
Сообщение об ошибке:
Свойство activeBusinessCase является частным и доступно только в пределах класса UserAuthService.
My user-auth.service.ts
login(name: string, password: string, imTid: string): Observable<UiInfo> {
return this.loginWithBackend(name, password, imTid).pipe(
tap(() => {
this.user.user_name = translate('default-user');
// TODO: Check if loggedoff is obsolete?
if (this.loggedOff) {
this.pls.back();
} else if (this.redirectUrl) {
this.router.navigate([this.redirectUrl]);
this.redirectUrl = null;
console.log(Constants.texts.loginSuccessRedirect);
} else {
console.log('Active Business Case', this.activeBusinessCase);
if (this.activeBusinessCase) {
this.router.navigate([Constants.routing.explorer + this.activeBusinessCase.toLowerCase()]);
} else {
const err = new LoginError('Business case is missing');
throw err;
}
}
this.loggedOff = false;
}));
Сообщение об ошибке:
Свойство 'toLowerCase' не существует для типа 'BehaviorSubject'.
My home.component.ts
export class HomeComponent implements OnInit {
routing = Constants.routing;
constructor(private router: Router,
private authService: UserAuthService) {
}
ngOnInit() {
this.router.navigate([Constants.routing.explorer + this.authService.activeBusinessCase.toLowerCase()]);
}
}
Сообщение об ошибке:
Свойство activeBusinessCase является закрытым и доступно только в классе UserAuthService.