読者です 読者をやめる 読者になる 読者になる

angular2 post通信

angular

angular2でPOST通信をしようとしたら、エラーになった。
subscribeした後に、console.log出力しようとすると、undefinedのエラーになる。
たぶんsubscribeの中でRxJSが実際のPOST通信をしているけど、非同期でやっているので、
完了する前に、応答を格納する変数にアクセスしようとすると、エラーになる。

subscribeの3番目の引数(関数?)がonCompletedだったので、
そこでPOST通信完了後の処理を書いたらうまくいった(と思う)。

my sample

"angular2": "2.0.0-beta.12",

import {Injectable} from 'angular2/core';
import {Jsonp, URLSearchParams, Headers, Http, Response} from 'angular2/http';
import {Observable} from 'rxjs/Rx';

export interface LoginResult {
    result: string;
    username: string;
}

@Injectable()
export class LoginService {
  constructor(private jsonp: Jsonp, private http: Http) {}

  private loginRes: LoginResult;
  
  login (username: string, password: string) {
      let res = this._query(username, password);
      res.subscribe(
          updatedLogin => { this.loginRes = updatedLogin },
          error => console.log('Error login (http post)'),
          () => {
              // onCompleted
              this._after_query()
          }
      );
      
      // undefined error
      console.log("username:" + this.loginRes.username);
  }
  
  private _after_query() {
      // TODO 
      
      console.log("username:" + this.loginRes.username);
      console.log("result:" + this.loginRes.result);
  }
  
  private _query(username, password):Observable<LoginResult> {
      let url = '/mock_login';
      var params = new URLSearchParams();
      params.set('action', 'login');
      params.set('username', username);
      params.set('password', password);
      let headers = new Headers();
      //headers.append('Content-Type', 'application/json');
      headers.append('Content-Type', 'application/x-www-form-urlencoded');
      
      return this.http.post(url, params.toString(), {
        headers: headers
        })
        .map((res:Response) => res.json());
  }
}

https://github.com/Reactive-Extensions/RxJS/blob/master/doc/api/core/operators/subscribe.md

mock json

Cannot POST /dummy_json/login_result.json( npm local-web-server のインストール) - kubotti’s memo

error memo

e: TypeError: undefined is not an object (evaluating 'this.loginRes.username')

EventEvaluationErrorContext {element: <form>, componentElement: <login>, context: LoginComponent, locals: Object, injector: Injector}
[Log] EXCEPTION: Error during evaluation of "submit" (angular2.dev.js, line 23607)
[Error] EXCEPTION: Error during evaluation of "submit"
    logError
    logGroup
    call
    (anonymous function)
    _notifyOnError
    onError
    run
    (anonymous function)
    run
    outsideHandler
    run
    zoneBoundFn
ORIGINAL EXCEPTION: TypeError: undefined is not an object (evaluating 'this.loginRes.username')
logErrorangular2.dev.js:23738
callangular2.dev.js:1267
(anonymous function)angular2.dev.js:12604
_notifyOnErrorangular2.dev.js:13649
onErrorangular2.dev.js:13549
runangular2-polyfills.js:1315
(anonymous function)angular2.dev.js:13573
runangular2.dev.js:13531
outsideHandlerangular2.dev.js:13365
runangular2-polyfills.js:1312
zoneBoundFnangular2-polyfills.js:1289
EventEvaluationErrorContext
componentElement: login {title: "", lang: "", translate: true, dir: "", tabIndex: -1, …}
context: LoginComponent {router: ChildRouter, http: Http, _loginService: LoginService, login3: function, login: function, …}
element: form {0: <input id="username2">, 1: <input id="password2">, 2: <button class="btn btn-default">, acceptCharset: "", action: "", autocomplete: "", enctype: "application/x-www-form-urlencoded", …}
injector: Injector {_isHostBoundary: true, _depProvider: AppElement, _debugContext: function, _constructionCounter: 1, _proto: ProtoInjector, …}
locals: {username: <input id="username">, password: <input id="password">, username2: <input id="username2">, password2: <input id="password2">}

メモ

      let res1 = this.http.post(url, params.toString(), {
        headers: headers
        });

の戻り値は、Observable
_subscribe というfunctionがメンバーにある。

this.http.post(url, params.toString(), {
        headers: headers
        })
        .map((res:Response) => res.json());

の戻り値は、Observable
operator: MapOperator
source: Observable (中に_subscribe というfunctionがメンバーにある)

Rx.js 11214 Line

: TypeError: undefined is not an object (evaluating 'this.loginRes.result')  

  query(username, password):Observable<LoginResult> {  
Observable<T>  

ジェネリクスの型指定。