Rendering HTML response from REST API in a React App

286 Views Asked by At

I have a react app in which I want to display a chart generated in Python that is fetched via a REST API (AWS Lambda).

The api fetches the html as expected (I see it in the console) and the rest of the components are rendered as expected but I can't manage to render HTML from the response on the screen. I can see the "Loading..." while it is fetching the HTML response but once it resolves it does not display on the screen despite the HTML showing in the dev tools. Am I missing something here? Does it have to do with the mounting/dismounting?

AWS Lambda API:

import json
import matplotlib.pyplot as plt
import numpy
import mpld3
import pandas as pd

def lambda_handler(event, context):
    # TODO implement
    
    fig = plt.figure()
    
    plt.plot([1, 2, 3, 4])
    plt.ylabel('some numbers')
    
    #fig = plt.figure(figsize = (18,8))
    html_str = mpld3.fig_to_html(fig, template_type='general', no_extras='true')
    test_str = 'Hello'
    #fig.show()
    response = {
        "statusCode": 200,
        #"headers": { "Content-Type": "text/html" },
        "headers": {
            'Access-Control-Allow-Headers': '*',
            'Access-Control-Allow-Origin': '*',
            'Access-Control-Allow-Methods': 'OPTIONS,POST,GET',
            'Content-Type': 'text/html'
        },
        "body": html_str
    };

    return response;

React code to fetch the chart:

import React, { useState, useEffect } from 'react';

export default function Plot() {
  
  const [responseData, setResponseData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  useEffect(() => {
    fetch(****) // my api url
      .then(response => response.text())
      .then((usefulData) => {
        console.log(usefulData);
        setLoading(false);
        setResponseData(usefulData);
      })
      .catch((e) => {
        console.error(`An error occurred: ${e}`)
      });
  }, []);

  return (
    <>
      <div className="App">
        {loading && <p>Loading...</p>}
        {!loading && <div dangerouslySetInnerHTML={{ __html: responseData }} />}
      </div>
    </>
  )
}

React code to display the HTML:

import Button from 'react-bootstrap/Button';
import Form from 'react-bootstrap/Form';
import Plot from './Plot';

function HomePageForm() {
  return (
    <>
    <Form>
      <Form.Group className="mb-3" controlId="formDataSet">
        <Form.Label>Test Label</Form.Label>
        <Form.Control type="file" />
      </Form.Group>

      <Form.Select aria-label="Algorithm">
        <option>test options...</option>
        <option value="1">option 1</option>
        <option value="2">option 2</option>
        <option value="3">option 3</option>
      </Form.Select>
    </Form>
    <Plot />
  </>
    
  );
}
export default HomePageForm;
0

There are 0 best solutions below