订阅不在角度服务内工作。异步问题?

时间:2018-02-18 02:30:54

标签: angular

我有一个用户输入linux用户名和日期的表单。 此信息用于创建新的"委托"在数据库中输入。在我可以调用我的REST API之前,我需要将此linux用户名转换为相应用户记录的主键,因为POST调用需要此表单数据:

{ 
   'delegator': <user pk>, 
   'delegatee': <user pk>, 
   'expiration': <string for data YYYY-MM-DD>
}

所以我有这个服务从数据库中获取用户:

import { Injectable } from '@angular/core';
import {Headers, Http } from '@angular/http';

import 'rxjs/add/operator/toPromise';
import 'rxjs/add/operator/map';
import {environment} from '../../../environments/environment';

@Injectable()
export class UserService {

  private headers = new Headers({'Content-Type': 'application/json'});

  constructor(private http: Http) {}
  getUsers(login: string)  {
    var url = environment.apiUrl + '/api/v1/users' + '/?autocomplete=1&login=' + login + '&type=employee';
    return this.http.get(url).map(res => <string[]>res.json());
  }
}

该服务返回格式为"login:user_id"的字符串数组。 UserService正常,我将在下面显示。

我在另一项服务getUsers()中致电DelegationsService。以下是DelegationsService中定义的调用getUsers()的方法:

export class DelegationsService {

  private headers = new Headers({'Content-Type': 'application/json'});
  delegatees: string[];

  constructor(private http: Http, private userService: UserService) {}

  newDelegation (delegator: number, delegatee_login: string, expiration: string) {
    // translate the login of the delegatee_login into the userid for the delegatee.
    var resp = this.userService.getUsers(delegatee_login).subscribe((delegatees) => {
        this.delegatees = delegatees;
        console.log(this.delegatees);
        console.log( this.delegatees[0]);
        var delegatee_id = this.delegatees[0].split(':')[1];
        console.log( 'newDelegation line 42 : ' + delegatee_id );
    });
    if ( this.delegatees ) {
        console.log( 'newDelegation line 52 : ' + this.delegatees[0] );
    } else {
        console.log( 'newDelegation line 54 no delegatees returned' );
    }
    // make a fake body since we can't the the delegatee's user id.
    var body = { 'delegator': delegator.toString(), 'delegatee': '9999', 'expiration': expiration };
    console.log(body);
    return this.http.post(environment.apiUrl + '/api/v1/delegation', body );
  }

有些注意事项:我在subscribe()中有调试代码,证明我确实从getUsers()调用中获取了数据。

调用newDelegations()时,浏览器中的控制台输出为:

newDelegation line 54 no delegatees returned
delegations-service.services.ts:57 {delegator: "975197", delegatee: "9999", expiration: "4000-04-04"}
delegations-service.services.ts:39 ["red:880922"]
delegations-service.services.ts:40 red:880922
delegations-service.services.ts:42 newDelegation line 42 : 880922

正如我们从上面的输出中可以看到,第54行在第39行之前执行。而第39行所在的订阅代码块具有从getUsers()调用返回的数据,而第54行则没有。

我做错了什么?

更新:我根据iHazCode的建议重写了newDelegation方法。

  newDelegation (delegator: number, delegatee_login: string, expiration: string) {
    this.userService.getUsers(delegatee_login).subscribe((delegatees) => {
        this.delegatees = delegatees;
        console.log(this.delegatees);
        console.log( this.delegatees[0]);
        var delegatee_id = this.delegatees[0].split(':')[1];
        console.log( 'newDelegation line 42 : ' + delegatee_id );
        var body = { 'delegator': delegator.toString(), 'delegatee': delegatee_id, 'expiration': expiration };
        console.log(body);
        return this.http.post(environment.apiUrl + '/api/v1/delegation', body );
    });
  }

当上述代码执行时,对我的浏览器的网络选项卡中没有出现对/ api / v1 / delegation的调用。只是由getUsers()执行的get()请求。

更新II。以下是调用newDelegation()

的代码
export class DelegationDetailComponent implements OnInit {

  userid: number;
  login: string;
  @Input() delegation: Delegation;
  constructor(
    private delegationService: DelegationsService,

  ) {
    // faking this for now until authentication is working.
    this.userid = 975197;
    this.login = 'red2';
  }

...

  onSubmitNewDelegation(f: NgForm): void {
    console.log( 'Update delegation with id ' + f.value.delegator);
    this.delegationService.newDelegation(
                   f.value.delegator,f.value.delegatee,f.value.expiration);
    }
    ...

2 个答案:

答案 0 :(得分:1)

简单的解决方案是从if语句移动所有内容:

if (this.delegatees) etc...

进入(async)getUsers调用的订阅块。

希望这有帮助

var resp = this.userService.getUsers(delegatee_login).subscribe((delegatees) => {
        this.delegatees = delegatees;
        console.log(this.delegatees);
        console.log( this.delegatees[0]);
        var delegatee_id = this.delegatees[0].split(':')[1];
        console.log( 'newDelegation line 42 : ' + delegatee_id );
    if ( this.delegatees ) {
        console.log( 'newDelegation line 52 : ' + this.delegatees[0] );
    } else {
        console.log( 'newDelegation line 54 no delegatees returned' );
    }
    // make a fake body since we can't the the delegatee's user id.
    var body = { 'delegator': delegator.toString(), 'delegatee': '9999', 'expiration': expiration };
    console.log(body);
    return this.http.post(environment.apiUrl + '/api/v1/delegation', body );
    });
}

答案 1 :(得分:1)

请尝试:

    onSubmitNewDelegation(f: NgForm): void {
        console.log( 'Update delegation with id ' + f.value.delegator);
        this.delegationService.newDelegation(
                       f.value.delegator,f.value.delegatee,f.value.expiration).subscribe((result) => {
      console.log(result);
   });

}

希望这有帮助。

P.S。我只让它将结果发送到控制台,以便您可以检查或网络选项卡以确保您的POST现在正在发生。