2016-09-19 61 views
1

下面是我的组件文件和服务文件。我想要做的是在其成功回调之后的后验证()服务方法,即在订阅内我想调用另一种服务方法,即注册()。但是,它不工作我展示以下错误:如何使用observables在Angular2中创建嵌套的Service调用?

enter image description here

angular1

以前,如果我做到这一点的工作,但不是在这里:

sampleService.meth1().success(function(){ 
      //statement1... 
      sampleService.meth1().success(function(data){ 
      //statement2... 
     }).error(function(){}) 
    }).error(function(){}); 
}) 

Signup.component.ts

import { Component, Input } from '@angular/core'; 
    import { Router } from '@angular/router'; 
    import {User} from '../shared/model/user'; 
    import {SignupService} from './signup.service'; 
    import 'rxjs/add/operator/map'; 
    import 'rxjs/add/operator/catch'; 
    import 'rxjs/add/operator/debounceTime'; 
    import 'rxjs/add/operator/distinctUntilChanged'; 
    import 'rxjs/add/operator/switchMap'; 
    import 'rxjs/add/operator/toPromise'; 

    @Component({ 
     moduleId: module.id, 
     selector: 'ym-signup', 
     templateUrl: 'signup.component.html', 
     styleUrls: ['signup.component.css'], 
     providers: [SignupService] 
    }) 

    export class SignupComponent { 

     @Input() 
     user = {}; 

     constructor(private router:Router, private signupService:SignupService) { 
     } 

     signup(selectedUser:User) { 
      this.signupService.verification(selectedUser) 
       .subscribe(data => { 
         swal({ 
          title: 'Verify token sent on your Email.', 
          input: 'password', 
          inputAttributes: { 
           'maxlength': 10, 
           'autocapitalize': 'off', 
           'autocorrect': 'off' 
          } 
         }).then(function (password) { 

          this.signupService.signup(password) 
           .subscribe(data => { 

             localStorage.setItem('user', JSON.stringify(data)); 
             this.router.navigate(['dashboard']); 
            }, 
            error => alert(error)); 
         }) 
        }, 
        error => alert(error)); 
     } 


     goBack() { 
      this.router.navigate(['login']); 
     } 
    } 

注册.service.ts

import {User} from '../shared/model/user'; 
import { Headers, Http } from '@angular/http'; 

import 'rxjs/add/operator/toPromise'; 
import {Injectable} from '@angular/core'; 
import {Response} from "angular2/http"; 
import { Observable }  from 'rxjs/Observable'; 


@Injectable() 
export class SignupService { 

    private postUrl:string = '/api/users/signup'; 
    private verify:string = '/api/users/verify'; 
    constructor(private http:Http) { 
    } 

    verification(user:User):Observable<JSON> { 
     let headers = new Headers({ 
      'Content-Type': 'application/json' 
     }); 

     return this.http 
      .post(this.verify, JSON.stringify(user), {headers: headers}) 
      .map(this.extractData) 
      .catch(this.handleError); 
    } 

    signup(token:string):Observable<any> { 
     let headers = new Headers({ 
      'Content-Type': 'application/json' 
     }); 

     return this.http 
      .post(this.postUrl, JSON.stringify({verificationToken:token}), {headers: headers}) 
      .map(this.extractData) 
      .catch(this.handleError); 
    } 

    private extractData(res: Response) { 
     let body = res.json(); 
     return body || { }; 
    } 

    private handleError(error: any) { 
     let errMsg = (error.message) ? error.message : 
      error.status ? `${error.status} - ${error.statusText}` : 'Server error'; 
     console.error(errMsg); 
     return Observable.throw(errMsg); 
    } 

} 
+2

使用方向的功能,而不是'function' –

回答

2

在注册方法,你都给人一种功能的回调然后。 您应该像箭头函数一样保持相同的上下文。

signup(selectedUser:User) { 
      this.signupService.verification(selectedUser) 
       .subscribe(data => { 
         swal({ 
          title: 'Verify token sent on your Email.', 
          input: 'password', 
          inputAttributes: { 
           'maxlength': 10, 
           'autocapitalize': 'off', 
           'autocorrect': 'off' 
          } 
         }).then(password => { 

          this.signupService.signup(password) 
           .subscribe(data => { 

             localStorage.setItem('user', JSON.stringify(data)); 
             this.router.navigate(['dashboard']); 
            }, 
            error => alert(error)); 
         }) 
        }, 
        error => alert(error)); 
     } 
3

由错误Cannot read property 'signup' of undefined它看起来当你是一个不存在的对象上调用signup()喜欢看。

这是正确的,你创建封闭为.then(function (password) { ... })它不捕获周围的上下文this,因此调用this = window这是不是你想要的显然。

参见:https://basarat.gitbooks.io/typescript/content/docs/arrow-functions.html

所以,你可以很容易地用箭头功能修复:

.then(password => { 
    this.signupService.signup(password) 
     .subscribe(data => { 
      localStorage.setItem('user', JSON.stringify(data)); 
      this.router.navigate(['dashboard']); 
     }, error => alert(error)); 
}) 
+0

THX它的工作我没想到的是sweetalert是造成问题。还有一件事,如果你可以在验证()成功后提供帮助,我希望提示用户输入,然后在调用之前将该输入放入signup()方法中。 –

+0

好吧,在调用'this.signupService.signup(password)之前最容易......用JavaScript的标准'prompt()'函数向用户询问凭证,该函数显示一个弹出窗口。请参阅http://www.w3schools.com/jsref/met_win_prompt.asp 然后使用'signup()'方法中的值 – martin

-1

使用Observable.forkJoin()来同时运行多个http.get()请求。如果任何单个请求失败,整个操作将导致错误状态。 请找到下面的代码片段用法:

getBooksAndMovies() { 
     Observable.forkJoin(
      this.http.get('/app/books.json').map((res: Response) => res.json()), 
      this.http.get('/app/movies.json').map((res: Response) => res.json()) 
     ).subscribe(
      data => { 
       this.books = data[0] 
       this.movies = data[1] 
      }, 
      err => console.error(err) 
     ); 

相关问题