I put this.useraccountsubject(user) to interpolate information on login, but I get an error :
ErrorType: this.useraccount.next(user) then Error An argument of type 'HttpResponse' is not allowed against a balance of 'Useraccount'
auth service.ts :
export class AuthService {
private useraccountSubject: BehaviorSubject<Useraccount> =
new BehaviorSubject<Useraccount>(new Useraccount("", "", "", "", ""));
public user: Observable<Useraccount> =
this.useraccountSubject.asObservable();
isLoggedIn = new BehaviorSubject(false);
constructor(private http:HttpClient, private router:Router){
this.useraccountSubject =
new BehaviorSubject<Useraccount>(null as any);
this.user = this.useraccountSubject.asObservable();
if(sessionStorage.getItem("USER")){
const user =sessionStorage.getItem("USER");
if(user){
this.useraccountSubject.next(JSON.parse(user));
}
}
}
private handleError(err: HttpErrorResponse) {
if (err.status === 200) {
console.error('Error:',err.error.data)
} else {
console.error(`Backend error ${err.status}`)
}
return throwError(err);
}
private handleErrorsingup(err: HttpErrorResponse) {
if (err.status === 201) {
console.error('Error:',err.error.data)
} else {
alert('faild');
console.error(`Backend error ${err.status}`)
}
return throwError(err);
}
login(username:string,password:string){
const params = new FormData();
params.append('username', username);
params.append('password', password);
return this.http.post<any>(`${baseUrl}/signin/`, params, { observe:'body', withCredentials: true})
.pipe(map(user=>{
catchError(this.handleError)
//edit !!
this.useraccountSubject.next(user);
sessionStorage.setItem("USER", JSON.stringify(user));
this.isLoggedIn.next(true);
return user;
}));
}
signup(email:string,password:string,name:string ){
const params = new FormData();
params.append('email', email);
params.append('password', password);
params.append('name', name);
return this.http.post<any>(`${baseUrl}/signup/`, params, { observe:'body', withCredentials: true })
.pipe(
catchError(this.handleErrorsingup)
);
}
logout(){
return this.http.post<any>(`${baseUrl}/signout/`, {})
.subscribe(response => {
this.isLoggedIn.next(false);
this.useraccountSubject.next(null as any)
sessionStorage.clear();
this.router.navigate(['login'])
})
}
//edit
setUseraccount(user: Useraccount): void {
this.useraccountSubject.next(user);
}
getUseraccount(): Observable<Useraccount> {
return this.useraccountSubject;
}
}
The format 'HttpResponse' does not have id, username, name, password, email attributes in the format 'Useraccount'.
Useraccount.ts:
export class Useraccount{
constructor(
public id:string,
public username: string,
public name: string,
public password: string,
public email: string
){}
}
I have for that format Useracount.ts
header.ts
export class HeaderComponent implements OnInit {
private userSubject: BehaviorSubject<Useraccount> = new
BehaviorSubject<Useraccount>(null); //edit null error An argument of type 'null' cannot be assigned to a parameter of type 'Useraccount'.
user:Observable<Useraccount> = this.userSubject.asObservable();
loginStatus?: boolean;
constructor(private authservice:AuthService) {
}
ngOnInit(): void {
this.authservice.getUseraccount().subscribe(res => {
if (res === null) {
// handler error
console.log(this.user);
} else {
this.user = res;//error this.user => res; //error There are no three attributes in the 'Useraccount' format other than source, operator, lift, and subscription in the 'Observable<Useraccount>' format.
let useraccountSubject: Useraccount = new Useraccount(res.id, res.username, res.email, res.password, res.name);
this.userSubject.next(useraccountSubject);
}
});
this.authservice.isLoggedIn.subscribe((status:any) => {
this.loginStatus = status;
});
}
logout($event: any){
$event.stopPropagation();
this.authservice.logout();
}
}
header.html
<ul *ngIf="!loginStatus" >
<li><a routerLink='/login' >login</a></li>
<li><a routerLink='/singup' >signup</a></li>
</ul>
<ul *ngIf="loginStatus">
<div *ngIf="user | async"> //edit
<li>{{( user | async).username }}</li>
</div>
<li><a (click)="logout($event)">logout</a></li>
</ul>
console
user: {id: 7, uuid: '11a25078-be87-4a53-9ff7-ead8777f79be', username:
'[email protected]', email: '[email protected]', name: 'beom', …}
[[Prototype]]: Object
The error is gone but the username is interpolated and doesn't appear in the header Could you please take a look at this issue?
CodePudding user response:
It's probably a problem with the types
try this adjustments to your code
First change User Class:
export class Useraccount {
constructor(
public id:string,
public username: string,
public name: string,
public password: string,
public email: string
){}
}
In AuthService :
private currentUser: BehaviorSubject<Useraccount> =
new BehaviorSubject<Useraccount>(new Useraccount("", "", "", "", ""));
login(username:string,password:string){
const params = new FormData();
params.append('username', username);
params.append('password', password);
return this.http.post<any>(`${baseUrl}/signin/`, params, { observe:'body', withCredentials: true})
.pipe(
catchError(this.handleErrorsingup)
);
}
logout(){
return this.http.post<any>(`${baseUrl}/signout/`, {})
.subscribe(response => {
this.isLoggedIn.next(false);
this.setCurrentUser(null);
sessionStorage.clear();
this.router.navigate(['login'])
}
In auth.serice create two new functions :
setCurrentUser(user: Useraccount): void {
this.currentUser.next(user);
}
getCurrentUser(): Observable<Useraccount> {
return this.currentUser;
}
In the header do this :
export class HeaderComponent implements OnInit {
private userSubject: BehaviorSubject<Useraccount> = new
BehaviorSubject<Useraccount>(null);
user:Observable<Useraccount> = this.userSubject.asObservable();
loginStatus?: boolean;
constructor(private authservice:AuthService) { }
ngOnInit(): void {
this.authservice.getCurrentUser().subscribe(res => {
if (res === null) {
// handler error
console.log(this.user);
} else {
this.user = res;
let currentUser: Useraccount = new Useraccount(res.userId, res.username, ...);
this.userSubject.next(currentUser);
}
})
this.authservice.isLoggedIn.subscribe((status:any) => {
this.loginStatus = status;
});
}
logout($event: any){
$event.stopPropagation();
this.authservice.logout();
this.user = null;
}
}
<ul *ngIf="!loginStatus" >
<li><a routerLink='/login' > 로그인</a></li>
<li><a routerLink='/singup' >회원가입</a></li>
</ul>
<ul *ngIf="loginStatus">
<ng-container *ngIf="user | async">
<li>{{( user | async).username }}</li>
</ng-container>
<li><a (click)="logout($event)">로그아웃</a></li>
</ul>
CodePudding user response:
I can't comment yet, so writing here.
I think its type cast issue. In the next method on BehaviorSubject, try creating Useraccount object for your data like
this.useraccountSubject.next(new Useraccount(user));
PS, in case it doesn't work try to use Useraccount as Interface.
CodePudding user response:
The problem is in this line
this.http.post<any>(`${baseUrl}/signin/`, params, {observe:'response', withCredentials: true})
The value of observe
should be body
this.http.post<Useraccount>(`${baseUrl}/signin/`, params, {observe:'body', withCredentials: true})
Look at Overload #15 in this (https://angular.io/api/common/http/HttpClient#post)