难以置信的回归未定义

时间:2017-11-19 04:07:35

标签: angular nativescript angular2-nativescript

我在登录用户时遇到问题。我正在使用的是nativescript-angular,使用rails 5 api运行devise_token_auth进行身份验证。真正奇怪的是,在服务器日志中,它显示正在完成的请求并返回200状态。此外,似乎observable本身或map函数返回undefined,我不知道为什么。如果有人能看一眼就会很棒。

auth.service.ts

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs'
import { Response, Http, Headers, RequestOptions, } from '@angular/http'
import * as Toast from 'nativescript-toast'
// import 'rxjs/add/operator/map'
// import 'rxjs/add/operator/catch'
// import 'rxjs/add/Observable/throw'

@Injectable()
export class AuthService {

  constructor(private http: Http) {}

  signinUser(signInData: { email: string, password: string }): Observable<Response> {
    let headers = new Headers;
    headers.append('Content-Type', 'application/json')
    let options = new RequestOptions({ headers: headers })
    let url = 'backend api'

    return this.http.post(url, signInData, options)
      .map((res: Response) => {
        let body = res.json()
        console.log("body: " + body)
        console.log('status: ' + res.json().status)
        Toast.makeText('status: ' + res.json().status).show();
        console.log('statusText: ' + res.json().statusText)
        Toast.makeText('statusText: ' + res.json().statusText).show();
        return body || null
      })
      .catch((error) => {
        return Observable.throw(error)
      })
  }
} 

signin.component.ts

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Rx'
import { Router, NavigationExtras } from '@angular/router'
import { FormGroup, FormControl, Validators, AbstractControl, FormBuilder } from '@angular/forms'
import { Http, Headers, RequestOptions, Response } from '@angular/http'
import { AuthService } from '../auth/auth.service'
import * as Toast from "nativescript-toast";

@Component({
  moduleId: module.id,
  selector: 'app-signin',
  templateUrl: './signin.component.html',
  styleUrls: ['./signin.component.css']
})
export class SigninComponent implements OnInit {
  signinForm: FormGroup;

  constructor(private router: Router,
              private http: Http,
              private fb: FormBuilder,
              private authService: AuthService) {}

  ngOnInit() {
    this.signinForm = this.fb.group({
      'email': new FormControl(null, [Validators.required, Validators.email,
                                      Validators.pattern("[a-zA-Z0-9.-_]{1,}@[a-zA-Z.-]{2,}[.]{1}[a-zA-Z]{2,}")]),
      'password': new FormControl(null, Validators.required) 
    })
  }

  onSignin(form: any) {
    const email = form.email
    const password = form.password

    this.authService.signinUser({ email, password })
      .subscribe(
        (res) => {
          if(res.statusText == 'OK') {
            this.router.navigate(['movies'])
          } else {
            console.log(res.status + ' FAILURE')
            Toast.makeText(res.status + ' FAILURE').show();
          }
        },
        (error) => {
          Toast.makeText(error.message).show();
        },
        () => { 
          console.log('IN SUBSCRIBE') 
          Toast.makeText('IN SUBSCRIBE').show();
        }
      )
  }
}

编辑1

继承控制台的内容

JS: body: [object Object]
JS: status: undefined
JS: statusText: undefined
JS: undefined FAILURE
JS: IN SUBSCRIBE

1 个答案:

答案 0 :(得分:0)

以下是发生的事情:

当你在响应上调用.json()时,它会获取响应的主体并在其上调用JSON.parse()并将该值返回给你。因此,响应状态和statusText之类的东西不在你从json()返回的值中,只有实际的json响应体存在。

如果您想访问这些内容,只需直接从您的服务中的响应对象中获取它们,如下所示:

return this.http.post(url, signInData, options)
  .map((res: Response) => {
    let body = res.json()
    console.log("body: " + body)
    console.log('status: ' + res.status)
    Toast.makeText('status: ' + res.status).show();
    console.log('statusText: ' + res.statusText)
    Toast.makeText('statusText: ' + res.statusText).show();
    return body || null
  })
  .catch((error) => {
    return Observable.throw(error)
  })

}

在您的组件中,您应该对其进行结构化,以便您的组件不需要关注响应状态等事情。这是一个服务级别的任务,如果它不是它需要的,那么使用Observable.throw()来确保它进入组件错误处理程序。值得一提的是,如果http服务得到任何类型的错误响应,它无论如何都会转到错误处理程序而不需要干预。

也是这篇文章:

.catch((error) => {
   return Observable.throw(error)
})
除非为了SO而删除了一些代码,否则

完全没有意义。您所做的只是重新抛出错误。