2016-07-24 72 views
0

我有一個通過道具傳遞給我的動作的redux形式。屬性this.props.userImages [0]是來自該表單上的文件輸入的圖像文件。然後,我將該圖像和XMLHttpRequest製作成Cloudinary,併爲該圖像生成一個url。一旦我收到url數據(xhr.responseText),我想將它與其他道具合併,然後我可以將所有道具發佈到API(所有表單信息+新創建的圖像URL)。如何在redux操作中處理XMLHttpRequests?

我知道我必須等待我的請求才能生成一個要解析的網址,但在將它傳遞到其他函數之前可能會遇到問題,可以在發佈之前將這些信息合併到道具中到我的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回調的東西。 – 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 
    });