My ApiClientService
takes an rxjs Service
as a parameter in all its methods to call APIs, subscribe to returned Observable
s, parse values, and then callback the Subject
's next()
.
However, in the UserService
class, a single Subject
used for multiple API calls does not trigger the second API's return. The API returns correctly, and Service.next()
is called with the expected value.
I'm wondering if this behavior (one service per Observable
) is intentional or if there is a design issue.
Thank you!
// ApiClientService.ts
@Injectable()
export class ApiClientService {
postUserLogin(userid: string, password: string): Observable<Object> {
const url = "/api/getforuser";
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
}
return this.http.post(url, { userid: userid }, httpOptions);
}
postSessionLogin(sessionid: string): Observable<Object> {
const url = "/api/getforsession";
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json',
})
}
return this.http.post(url, { sessionid: sessionid }, httpOptions);
}
}
UserService.ts
// UserService.ts
@Injectable()
export class UserService {
currentUser: UserModel;
constructor(
private apiclient: ApiClientService
) { }
isLoggedIn(): boolean {
if ( this.currentUser == null ) {
return false;
} else if ( this.currentUser.session != null ) {
if ( this.currentUser.session.length > 0 ) {
return true;
}
}
return false;
}
sessionLogin(userListener: Subject<UserModel>) {
console.log("UserService.sessionLogin");
var session = this.cookieService.get("session");
if ( session == null ) {
userListener.error("session not found");
} else {
var obRes = this.apiclient.postSessionLogin(session);
obRes.subscribe( res => {
console.log("sessionLogin response");
var payload = res['payload'];
console.log("payload: " + payload);
var user = payload['user'];
console.log("user: " + user);
this.currentUser = new UserModel;
this.currentUser.userid = user.userid;
userListener.next(this.currentUser);
});
}
}
userLogin(username: string, password: string, userListener: Subject<UserModel>) {
console.log("UserService.userLogin start");
var obRes = this.apiclient.postUserLogin(username, password);
obRes.subscribe( res => {
console.log("UserService.userLogin response start...");
console.log(res);
console.log("userLogin response json...");
var payload = res['payload'];
console.log("payload: " + payload);
var user = payload['user'];
console.log("UserService.userLogin user: " + user);
this.currentUser = new UserModel;
this.currentUser.userid = user.userid;
userListener.next(this.currentUser);
}, err => {
console.log("not even error, nothing...");
console.log(err);
});
}
}
The frontend component using UserService
// UserLoginComponent
@Component({
selector: 'app-home-login',
templateUrl: './home-login.component.html',
styleUrls: ['./home-login.component.scss']
})
export class HomeLoginComponent implements OnInit {
@Input() userModel: UserModel;
loggedinUser: UserModel;
userloginForm: FormGroup;
loginListener: Subject<UserModel>;
loginListenerSubs: Subscription;
constructor(private fb: FormBuilder,
private router: Router,
private userService: UserService
) {
this.createForm();
}
createForm() {
this.userloginForm = this.fb.group({
username: [ '', Validators.required ],
password: [ '', Validators.required ]
});
}
onSubmitLogin() {
this.userModel = this.pullFormContent();
this.userService.userLogin(this.userModel.username, this.userModel.password, this.loginListener);
}
pullFormContent() {
const formModel = this.userloginForm.value;
// Form content processing logic here
const user: UserModel = {
userid: 0,
username: formModel.username,
password: formModel.password,
}
return user;
}
onLoginSuccess(user) {
// Login success handling
}
onLoginFailed(error) {
// Login failure handling
}
onLoginCompleted() {
// Post login completion logic
}
ngOnInit() {
// Component initialization logic
}
ngOnDestroy() {
// Component cleanup logic
this.loginListenerSubs.unsubscribe();
}
}