2016-07-24 4 views
0

私は自分の行動に小道具を渡している還元型を持っています。プロパティthis.props.userImages [0]は、そのフォームに入力されたファイルからのイメージファイルです。私はそのイメージを作成し、XMLHttpRequestをCloudinalにして、そのイメージのURLを生成します。 URLデータ(xhr.responseText)を受け取ったら、他の小道具とマージして、すべての小道具をAPI(すべてのフォーム情報+新しく作成された画像URL)に投稿できるようにしたいと思います。還元アクションでXMLHttpRequestsを処理するには?

私は解決するためのURLを生成する要求を待つ必要があることを知っていますが、私はその情報を取得して投稿する前に小道具でマージすることができる私の他の機能に渡すことができます私のAPIに。

//.. 

function generateUrl(props) { 

    // Grabs image file from my form's file input and uploads 
    // to cloudinary service so that a URL can be generated 

    const cloudinaryURL = 'https://api.cloudinary.com/v1_1/<my_name>/image/upload'; 
    const apiKey = 'secret_key'; 
    const uploadPreset = 'test_preset'; 

    const data = new FormData(); 
    data.append('file', props.userImages[0]); 
    data.append('upload_preset', uploadPreset); 
    data.append('api_key', apiKey); 

    const xhr = new XMLHttpRequest(); 
    xhr.open('POST', cloudinaryURL, true); 
    xhr.send(data); 
    xhr.onReadyStateChange =() => { 
    if (xhr.readyState == 4 && xhr.status == 200) { 
     return JSON.parse(xhr.responseText); 
    } 
    }; 

    return xhr.onReadyStateChange(); 
} 

export function createReview(props) { 

const imageUrl = generateUrl(props); 

const mergedProps = //... 

    // Here I'd like to merge my newly generated 
    // url back into props before I post to my API like so... 

    const request = axios.post(`${REQUEST_URL}/api`, mergedProps) 
    return { 
    type: CREATE_REVIEW, 
    payload: request 
    } 
}; 

すべてのご協力をよろしくお願いいたします。

+0

「XMLHttpRequest」は、約束には関係なく、関連しません。私は約束の文脈での質問を理解していません。 – Sukima

+0

フォームデータを送信すると、準備状態が4でステータスが200の場合、XMLHttpRequestがresponseTextを返すのを待たなければならないと思うので、すぐに返すことはできません。準備完了状態および状態。それが正しいかどうか私に教えてください。ありがとう! – hidace

+0

それは正しいですが、それは約束とは関係ありません。また、XHRコールバックを使用しなければならないものは何も_return_しません。 – Sukima

答えて

1

これは、例XMLHttpRequestベースのコードの文脈における約束とは関係ありません。

onReadyStateChangeに割り当てられたコールバックが戻り値で何かを行うと仮定しています。代わりにその関数から返されたものは忠実に無視されます。

あなたが望むのは、別のコールバックで値を引き継ぐことです。

function generateUrl(props, callback) { 
    // Do things here 
    xhr.onReadyStateChange =() => { 
     if (xhr.readyState == 4 && xhr.status == 200) { 
     callback(JSON.parse(xhr.responseText)); 
     } 
    }; 
} 


generateUrl(props, (response) => { 
    const mergedProps = // Use response as expected. 
}); 

あなたは約束し、私たちは、これは実際にあなたがで始めたかったおそらくある約束を使用するように変換することができ、あなたの使用してES2015を述べたので。

function generateUrl(props) { 
    return new Promise((resolve, reject) => { 
    const cloudinaryURL = 'https://api.cloudinary.com/v1_1/<my_name>/image/upload'; 
    const apiKey = 'secret_key'; 
    const uploadPreset = 'test_preset'; 

    const data = new FormData(); 
    data.append('file', props.userImages[0]); 
    data.append('upload_preset', uploadPreset); 
    data.append('api_key', apiKey); 

    const xhr = new XMLHttpRequest(); 
    xhr.onReadyStateChange =() => { 
     if (xhr.readyState == 4) { 
     if (xhr.status == 200) { 
      resolve(xhr.responseText); 
     } else { 
      reject(new Error(`Failed HTTP request (${xhr.status})`)); 
     } 
    }; 
    xhr.onerror = reject; 

    xhr.open('POST', cloudinaryURL, true); 
    xhr.send(data); 
    }); 
} 

generateUrl(props) 
    .then(JSON.parse) 
    .then(results => { 
    // Do something with response 
    }) 
    .catch(error => { 
    // Do something with the error 
    }); 
関連する問題