Search code examples
reactjsreact-pdf

ReactJS : Fetch response not returning to componentDidMount; Failed to load PDF


In ReactJS, component not re-rendering after receiving Fetch response. So always seeing "Loading PDF..." message in screen

componentDidMount code is given below,

    componentDidMount() {
        const {getData} = this.props;
        let data =  getData();
        console.log(data)      // printed empty while fetch in progress
        this.setState({pdfData : data})
        console.log(this.state.pdfData) // printed empty while fetch in progress
    }

After fetch, getData value (data) is not printed. pdfData is not set, due to this component is not re-rendering. At the same time, array value is printed in getData().

rendering returned data as pdf using react-pdf library

    render() {
        return(
            <div style={{ width: 500 }}>
            <Document
                file={this.state.pdfData }
                onLoadSuccess={() => console.log("Success")}
                onLoadError = {(error) => console.log(error.message)}
            >
                <Page pageNumber={1} />
            </Document>
            </div>
        );

    }

getData is given below,

export const getData = id => async (dispatch) => {
    let response;
    try {
        response = API_CALL
        console.log(response)                // PDF raw data printed
        let rawLength = response.length;
        let array = new Uint8Array(new ArrayBuffer(rawLength));
        for (let i=0; i < rawLength; i++){
            array[i] = response.charCodeAt(i);
        }
        console.log(array);                 //array value printed
        return array;
    } catch (error) {
        dispatch(setError(error.message));
        throw error;
    }
};

Solution

  • Since your getData function is async, you will need to either await the result in componentDidMount or act on the promise (assuming you are already awaiting your API call). E.g.:

    With await:

    async componentDidMount() {
        const { getData } = this.props;
        let data =  await getData(); // <-- Await the async here
        this.setState({ pdfData: data });
    }
    

    Or with the promise:

    componentDidMount() {
        const { getData } = this.props;
        getData().then((data) => { // <-- Act on the promise result
          this.setState({ pdfData: data });
        });
    }