【问题标题】:TypeScript - http.get().subscribe() --> not setting variableTypeScript - http.get().subscribe() --> 没有设置变量
【发布时间】:2017-01-16 02:29:43
【问题描述】:

我正在尝试创建一个service.ts 文件,它将处理我在 TypeScript (AngularJs2) 中的所有 Http 请求。

现在我确实得到了正确的响应,但我无法访问 subscribe() 函数之外的属性。让我告诉你我的意思。

APICaller.service.ts:

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

import { Evenement } from './models/evenement.model';
import { Deelnemer } from './models/deelnemer.model';
import { Comment } from './models/comment.model';

@Injectable()
export class APICaller {
    http : Http
    baseUrl:string = "http://10.0.4.161:8080";

    constructor(@Inject(Http) httpService) {
        this.http = httpService;
    }

    addNewComment(deelnemerId:number, eventId:number, content:string) : Comment{
        let results:Comment = {id: 0, content:"", user: "", status: "", date: ""};

        this.http.post(this.baseUrl+"/evenementen/"
        +eventId +"/deelnemers/"+deelnemerId+"/addComment"
        ,{
            user: 'developer',
            content: content
        }).subscribe((response) => {
            results = response.json();
            console.log("results id: "+ results.id);
        });

        return results;
    }
}

component.ts:(最小化 - 仍然需要清理)

import { APICaller } from '../../apicaller.service';
import { Comment } from '../../models/comment.model';

@Component({    
    templateUrl: 'build/pages/deelnemer-details/deelnemer-details.html',
    providers: [APICaller]
})

export class DeelnemerDetails {   
    public deelnemer:any;
    public http:Http;
    public eventObj;
    public newComment;
    public comments;
    public editComment:any;


    constructor(private apiCaller : APICaller, private navCtrl: NavController, navParams : NavParams,  public toastCtrl : ToastController, public alertCtrl:AlertController, @Inject(Http) httpService) {
        this.eventObj = navParams.get("event");
        this.http = httpService;
        this.newComment = "";
        this.deelnemer={};
        this.editComment={
        id: -1,
        edit: false,
        content: ""
    }

        this.getDeelnemer(navParams.get("deelnemer"));
    }

    addNewComment(){
        let test:Comment = {id: 0, content:"", user: "", status: "", date: ""};

        console.log("deelnemer id "+this.deelnemer.id);
        console.log("eventObj id "+ this.eventObj.id);
        console.log("new comment : "+this.newComment);

        test = this.apiCaller.addNewComment(this.deelnemer.id, this.eventObj.id, this.newComment);

        console.log("new comment id: "+ test.id);

        this.comments.push(
           test
        );
        this.newComment="";

    }

回复和console.log()

所以似乎在.subscribe() 中它没有设置results 的值。

【问题讨论】:

    标签: angular typescript


    【解决方案1】:

    当服务器的响应到达时,您传递给subscribe(...) 的回调会在很久以后调用。 return results; 在发起对服务器的调用后立即被调用。

    如果你把代码改成

    @Injectable()
    export class APICaller {
        http : Http
        baseUrl:string = "http://10.0.4.161:8080";
    
        constructor(@Inject(Http) httpService) {
            this.http = httpService;
        }
    
        addNewComment(deelnemerId:number, eventId:number, content:string) : Observable<Comment>{
            let results:Comment = {id: 0, content:"", user: "", status: "", date: ""};
    
            return this.http.post(this.baseUrl+"/evenementen/"
            +eventId +"/deelnemers/"+deelnemerId+"/addComment"
            ,{
                user: 'developer',
                content: content
            }).map((response) => {
                console.log("results id: "+ results.id);
                return response.json();
            });
        }
    }
    

    你可以通过调用得到结果

    addNewComment(){
        let test:Comment = {id: 0, content:"", user: "", status: "", date: ""};
    
        console.log("deelnemer id "+this.deelnemer.id);
        console.log("eventObj id "+ this.eventObj.id);
        console.log("new comment : "+this.newComment);
    
        this.apiCaller.addNewComment(this.deelnemer.id, this.eventObj.id, this.newComment).subscribe(test => {
    
          console.log("new comment id: "+ test.id);
    
          this.comments.push(
             test
          );
          this.newComment="";
        });
    
       // code here (outside the callback passed to `subscribe(...)`) is again
       // executed before `result` arrives
    
    }
    

    异步执行具有传染性,一旦启动异步执行,就无法返回同步执行。

    我将subscribe() 更改为map(),因为.map() 返回一个Observable,调用者可以订阅它。 .subscribe() 返回一个 Subscription,在这种情况下对调用者来说毫无价值。

    【讨论】:

    • 我必须将我的退货编辑为Observable&lt;Comment&gt;,但是如何从退货声明中检索数据?既然test 也是Observable
    • 对不起,我忘记了返回类型。我还从呼叫站点添加了更多代码。您需要将所有依赖于结果的代码移动到 `subscribe(...)´ 回调中。
    • let test:Comment = {i... 这行让我很困惑。它似乎没有做任何事情。
    • 我收到了一个先前的错误,即 'id' 不是 'undefined' 的属性,所以我定义了它以查看发生了什么。也许可以成为我的 REST 服务
    • 很高兴听到 :) 感谢您的反馈。
    【解决方案2】:

    由于 http 请求是异步的,您无法返回结果,因为到达 return 语句时尚未收到结果。

    你可以使用回调:

    addNewComment(deelnemerId: number, eventId: number, content: string, callback: (comment: Comment) => void): void {
        let results:Comment = {id: 0, content:"", user: "", status: "", date: ""};
    
        this.http.post(`${ this.baseUrl }/evenementen/"${ eventId }/deelnemers/${ deelnemerId }/addComment`, {
            user: 'developer',
            content: content
        }).subscribe((response) => {
            console.log("results id: " + results.id);
            callback(response.json());
        });
    }
    

    然后:

    this.apiCaller.addNewComment(this.deelnemer.id, this.eventObj.id, this.newComment, (comment: Comment) => {
        console.log("new comment id: " + comment.id);
    
        this.comments.push(
           comment
        );
    
        this.newComment = "";
    });
    

    或承诺:

    addNewComment(deelnemerId:number, eventId:number, content:string): Promise<Comment> {
        let results:Comment = {id: 0, content:"", user: "", status: "", date: ""};
    
        this.http.post(`${ this.baseUrl }/evenementen/"${ eventId }/deelnemers/${ deelnemerId }/addComment`, {
            user: 'developer',
            content: content
        }).map((response) => {
            console.log("results id: " + results.id);
            return response.json();
        }).toPromise();
    }
    

    然后:

    this.apiCaller.addNewComment(this.deelnemer.id, this.eventObj.id, this.newComment).then((comment: Comment) => {
        console.log("new comment id: " + comment.id);
    
        this.comments.push(
           comment
        );
    
        this.newComment = "";
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-01-29
      • 1970-01-01
      • 2021-02-17
      • 2018-02-15
      • 1970-01-01
      • 2021-06-21
      • 2016-04-06
      • 2016-03-20
      相关资源
      最近更新 更多