繁体   English   中英

Angular2从组件中的服务调用登录功能并返回错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM