[英]Angular2 Call login function from service in component and return error
我试图调用服务HTTP方法并最终返回一条错误消息,但是经过一周的尝试(承诺,可观察到的东西...),我无法正常工作。 我希望有人能帮助我吗?
我是Angular2的新手,独自从事这个项目,没有其他人拥有Angular的专业知识。 我确实获得了为期3天的培训课程。
零件
@Component({
templateUrl: 'build/pages/login/login.html'
})
export class LoginPage {
error: string;
constructor(private navController: NavController, private auth: AuthService) {
}
private login(credentials) {
// Method calling the login service
// Could return an error, or nothing
this.error = this.auth.login(credentials);
// If there is no error and the user is set, go to other page
// This check is executed before previous login methode is finished...
if (!this.error && this.auth.user) {
this.navController.setRoot(OverviewPage);
}
}
}
验证服务
@Injectable()
export class AuthService {
private LOGIN_URL: string = "http://localhost:8080/rest/auth";
private USER_URL: string = "http://localhost:8080/rest/user";
private contentHeader: Headers = new Headers({
"Content-Type": "application/json"
});
errorMessage: string;
user: User;
constructor(private http: Http) {
}
login(credentials) {
let contentHeader = new Headers({
"Content-Type": "application/json"
});
this.http.post(this.LOGIN_URL, JSON.stringify(credentials), { headers: contentHeader })
.map(res => res.json())
.catch(this.handleError)
.subscribe(
data => this.handleLogin(data),
err => this.handleError
);
// could return an errorMessage or nothing/null
return this.errorMessage;
}
private handleLogin(data) {
let token = data.token;
this.getAccount(token);
}
private getAccount(token) {
let authHeader = new Headers({
"Content-Type": "application/json",
"X-Auth-Token": token
});
this.http.get(this.USER_URL, { headers: authHeader })
.map(res => res.json())
.catch(this.handleError)
.subscribe(
data => this.setUser(data),
err => this.errorMessage = err
);
}
private setUser(data) {
this.user = new User(data.naam, data.voornaam);
}
private handleError(error) {
// this.errorMessage is not saved?
if (error.status === 401) {
this.errorMessage = '401';
} else if (error.status === 404) {
this.errorMessage = '404';
} else {
this.errorMessage = 'Server error';
}
return Observable.throw(error.json() || 'Server error');
}
}
我认为您的问题是您的登录方法返回的是固定值( errorMessage
)。 由于login方法正在发出一个异步请求,即不会初始化该值,因此它将始终返回null。 如果要进行设置,我将使用login方法返回一个Observable
。
为了使事情变得更复杂,您似乎想在登录后进行连续调用以获取登录用户。 如果您不希望在完成两个调用之前都发出登录方法,则必须以某种方式组合它们。 我认为switch
可以做到这一点。
@Injectable()
export class AuthService {
private LOGIN_URL: string = "http://localhost:8080/rest/auth";
private USER_URL: string = "http://localhost:8080/rest/user";
private contentHeader: Headers = new Headers({
"Content-Type": "application/json"
});
user: User;
constructor(private http: Http) {
}
login(credentials) {
let contentHeader = new Headers({
"Content-Type": "application/json"
});
let response:Observable<Response> = this.http.post(this.LOGIN_URL, JSON.stringify(credentials), { headers: contentHeader });
//Take response and turn it into either a JSON object or
//a string error.
//This is an Observable<any> (any is returned by json())
let jsonResponse = response.map(res => res.json())
.catch(err => this.handleError(err));
//Take JSON object and turn it into an Observable of whatever the
//login request returns
//This is an Observable<Observable<any>> (Observable<any> is returned
//by handleLogin
let userResponse = jsonResponse.map(
data => this.handleLogin(data)
);
//Switch to the observable of the login request
//This is an Observable<any>, we will switch to the Observable<any>
//returned by handleLogin
let finalResponse = userResponse.switch();
//Hide actual response value from user. This will return an
//observable that will emit null on success and an error message
//on error
//Again, an Observable<any> since we're mapping to null
return finalResponse.map(res => null);
}
//We need to return this call as an observable so we can wire it into
//our chain
private handleLogin(data) {
let token = data.token;
return this.getAccount(token);
}
private getAccount(token) {
let authHeader = new Headers({
"Content-Type": "application/json",
"X-Auth-Token": token
});
let loginResponse = this.http.get(this.USER_URL, { headers: authHeader })
.map(res => res.json())
.catch((err) => this.handleError(err));
loginResponse.subscribe(
data => this.setUser(data)
);
return loginResponse;
}
private setUser(data) {
this.user = new User(data.naam, data.voornaam);
}
private handleError(error) {
let errorMessage = "Uninitialized";
if (error.status === 401) {
errorMessage = '401';
} else if (error.status === 404) {
errorMessage = '404';
} else {
errorMessage = error.json() || 'Server error';
}
return Observable.throw(errorMessage);
}
}
现在,在登录组件中,您将需要异步侦听响应。 这不会立即发生(对于localhost来说可能很快,但是在现实世界中可能要花一些时间),因此我添加了loginDisabled,可以用来防止用户在等待登录请求时两次按下登录按钮要实现。
@Component({
templateUrl: 'build/pages/login/login.html'
})
export class LoginPage {
error: string;
loginDisabled:boolean = false;
constructor(private navController: NavController, private auth: AuthService) {
}
private login(credentials) {
// Method calling the login service
// Could return an error, or nothing
this.loginDisabled = true;
this.auth.login(credentials).subscribe(
rsp => {
//On success, navigate to overview page
this.navController.setRoot(OverviewPage);
}, err => {
//On failure, display error message
this.error = err;
this.loginDisabled = false;
});
}
}
没有保证这是完全正确的(我没有任何可测试的依据),但这应该是正确的总体方向。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.