2016-07-24 3 views
0

나는 내 행동에 소품을 전달하는 redux-form을 가지고있다. this.props.userImages [0] 속성은 해당 양식에 입력 된 파일의 이미지 파일입니다. 그런 다음 해당 이미지를 가져 와서 XMLHttpRequest를 Cloudinary로 보내면 해당 이미지에 대한 URL이 생성됩니다. 일단 URL 데이터 (xhr.responseText)를 받으면 다른 모든 소품과 병합하여 API (모든 양식 정보 + 새로 만든 이미지 URL)에 내 소품을 게시 할 수 있습니다.redux 액션에서 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 
    }); 
관련 문제