2016-05-15 2 views
0

flatMapRx.DOM.getJson()と動作するのに苦労しているし、何が間違っているのか分からない。Rx.Dom.getJsonからRx.DOM.getJsonへのRxJsのフラットマップは発砲しない

HTML

<!DOCTYPE html> 
<html> 
<head> 
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.all.js"></script> 
    <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs-dom/7.0.3/rx.dom.js"></script> 
<script src="https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-xta1/t39.3284-6/12624096_747368668729465_1053913233_n.js"></script> 
<script src="https://fbcdn-dragon-a.akamaihd.net/hphotos-ak-xaf1/t39.3284-6/12624065_1518596455100766_427485197_n.js"></script> 
    <title>JS Bin</title> 
</head> 
<body> 
    <button id='fetch'>Fetch</button> 
    <div id="content"></div> 
</body> 
</html> 

javascriptの

// Actions 
const Actions = { 
    LoadPosts: 'LoadPosts' 
}; 

// Disptacher 
const Dispatcher = new Rx.Subject(); 

function send(action) { 
    Dispatcher.onNext({action: action}); 
} 

// Stores 
const url = 'http://jsonplaceholder.typicode.com/posts'; 

const FetchedPosts$ = Dispatcher 
    .filter(x => Actions.LoadPosts === x.action) 
    .do(x => console.log(x)) 
    .flatMap(() => { 
    console.log('flat'); 
    return Rx.DOM.getJSON(url); 
    }) 
    .do(x => console.log('after', x)); 

// Views 
const fetchButton = document.getElementById('fetch'); 
const Fetch$ = Rx.Observable.fromEvent(fetchButton, 'click') 
    .do(x => send(Actions.LoadPosts)); 

const PostsView$ 
    = FetchedPosts$.map(posts => posts.map(post => <li>{post.title}</li>)); 

const RootView$ = Rx.Observable.merge(Fetch$, PostsView$); 

RootView$.subscribe(
    content => ReactDOM.render(
    <ul>{content}</ul>, 
    document.getElementById('content') 
) 
); 

出力

[object Object] { 
    action: "LoadPosts" 
} 
"flat" 
"Script error. (line 0)" 

だから出力は、私はグラムだということを示して私はフラットマップへのettingと私はRx.DOM.getJSON(url)を引っ張って、それを購読すれば、私は返される値を書くことができます。しかし、flatMapから何も返されず、Rxが以下に示すようにリクエストをキャンセルしていることを示すネットワークタブにエラーが表示されます。

enter image description here

ここJsBinだ:私はちょうど削除が反応していることに気づいhttp://jsbin.com/geruzo/edit?js,console,output

編集 Rx.DOM呼び出しが成功することができます。

答えて

1

私はあなたのjsbinコードを参照して回答します。これは投稿されたコードとは異なりますが、確認するのが簡単でした。すべての

まず、あなたのコードの修正版は、ここで見つけることができます http://jsbin.com/yugener/edit?html,js,output

あなたの最初の問題は、「LoadPosts」アクションが発生するボタンを、クリックしなくても、レンダリングごとに解雇されたということです無限レンダーループ。レンダー> LoadPosts->レンダー> LoasPosts ...

// The send will just be executed when the component is rendered 
<button click={send(Actions.LoadPosts)}>fetch</button> 

それは(ものonClick、代わりにクリックする)必要があります:レンダリングループがあったので

<button onClick={() => send(Actions.LoadPosts)}>Fetch</button> 

、および "LoadPosts" Rx.DOM.getJSONが前のリクエストが終了する前に再度呼び出されたため、前のリクエストが取り消されます。キャッチオペレータはあなたが観測を返すことを期待し、あなたがしなかったので、未定義のは、返されたRXJSで

.flatMap(() => Rx.DOM.getJSON('http://jsonplaceholder.typicode.com/posts')) 
.catch(error => console.log('error', error)) 

:あなたはより(など中断されましリクエストで)スローされたエラーを取得し、それをキャッチします今度は次のエラー提起:毎回「LoadPosts」アクションが起動されるので、注意点として

Uncaught TypeError: Cannot read property 'subscribe' of undefined 

を、あなたのケースではなく、flatMapを使用して、あなたは、switchMap(別名flatMapLatest)を使用する必要があり、あなたがしたいですすべての以前の要求を無視し、最後の要求からのみデータを取得します。 2つの違いの詳細については、flatMap vs switchMapを参照してください。以前の要求を設計によって中止したい場合は、以前の観測値がもはや値を出力していないため、flatMapは「中止」エラーを回避します。

+0

詳細返信いただきありがとうございます。.catch()のエラーを記録するための良いパターンについての詳細はありますか? –

+0

私たちはまた、最高のパターンを探しています。しかし、今のところ、catch()では、Observable.empty()をログに記録して戻すか、エラーオブジェクトを出力するobservableを返して返すことができ、UIに何らかのエラーが表示されます。 – omerts

関連する問題