最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

reactjs - React UI Not Displaying Backend API Response - Stack Overflow

programmeradmin3浏览0评论

I have a React application that makes a POST request to a backend API to process an image. The backend correctly processes the request and returns the expected response. However, the UI is not displaying the output correctly.

import React, { useState } from "react";
import axios from "axios";
import { useDropzone } from "react-dropzone";

interface ExtractedData {
  company: string;
  invoice_date: string;
  items: { description: string; quantity: number; amount: string }[];  // Changed amount to string for "$745.00" format
  total_amount: string;
  practitioner: string;
  patient: string;
  location: string;
  currency: string | null;
  other_details?: string;
}

const ImageUploadOCR: React.FC = () => {
  const [image, setImage] = useState<File | null>(null);
  const [data, setData] = useState<ExtractedData | null>(null);
  const [loading, setLoading] = useState<boolean>(false);

  const { getRootProps, getInputProps } = useDropzone({
    accept: { "image/*": [] },
    onDrop: (acceptedFiles) => setImage(acceptedFiles[0]),
  });

  const handleUpload = async () => {
    if (!image) return;

    setLoading(true);
    const formData = new FormData();
    formData.append("image", image);

    try {
      console.log("Data disk reached");
      const response = await axios.post("http://localhost:5000/api/extract", formData, {
        headers: { "Content-Type": "multipart/form-data" },
      });

      // Log the full response to verify the structure
      console.log("Response data:", response.data);

      // Set data to the state
      setData(response.data);

      // Optionally log company and invoice_date for debugging
      console.log("Company:", response.data?pany);
      console.log("Invoice Date:", response.data?.invoice_date);
    } catch (error) {
      console.error("Error uploading image:", error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="p-6 max-w-2xl mx-auto">
      <div {...getRootProps()} className="border-2 border-dashed p-4 cursor-pointer text-center">
        <input {...getInputProps()} />
        {image ? <p><img src={URL.createObjectURL(image)} /></p> : <p>Drag & drop an image, or click to select</p>}
      </div>
      <button className="mt-4 bg-blue-500 text-white px-4 py-2 rounded" onClick={handleUpload} disabled={!image || loading}>
        {loading ? "Processing..." : "Upload & Extract"}
      </button>

      {data && (
        <div className="mt-6">
          <h2 className="text-xl font-bold mb-2">Extracted Data</h2>
          <table className="w-full border-collapse border border-gray-300">
            <thead>
              <tr>
                <th className="border p-2">Field</th>
                <th className="border p-2">Value</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td className="border p-2">Company</td>
                <td className="border p-2">{data?pany || "Not available"}</td> {/* Optional chaining added */}
              </tr>
              <tr>
                <td className="border p-2">Invoice Date</td>
                <td className="border p-2">{data?.invoice_date || "Not available"}</td> {/* Optional chaining added */}
              </tr>
            </tbody>
          </table>

          <h3 className="text-lg font-bold mt-4">Items</h3>
          <table className="w-full border-collapse border border-gray-300">
            <thead>
              <tr>
                <th className="border p-2">Description</th>
                <th className="border p-2">Quantity</th>
                <th className="border p-2">Amount</th>
              </tr>
            </thead>
            <tbody>
              {data.items.map((item, index) => (
                <tr key={index}>
                  <td className="border p-2">{item.description}</td>
                  <td className="border p-2">{item.quantity}</td>
                  <td className="border p-2">{item.amount}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
};

export default ImageUploadOCR;

Issue: The API returns the expected result, but the UI does not display the image. No errors are shown in the console.

Backend response:

{'Currency': None, 'Location': '102 Trope Street, New York, NY 45568', 'Other relevant details': {'Due date': '07/30/23', 'Invoice number': '12245', 'Note': 'A prescription has been written out for patient, for an acute throat infection.', 'Subtotal': '$745.00', 'Tax amount': '$157.05', 'Tax rate': '9%'}, 'Patient': 'Kemba Harris', 'Practitioner': 'Dr. Alanah Gomez', 'Total Amount': '$1,902.05', 'company': 'Not specified', 'invoice_date': '07/01/23', 'items': [{'Amount': '$745.00', 'Description': 'Full Check Up', 'Quantity': '1'}, {'Amount': '$1,000.00', 'Description': 'Ear & Throat Examination', 'Quantity': '1'}]}

How can I properly display the image output in the UI? What could be causing the issue?

I have a React application that makes a POST request to a backend API to process an image. The backend correctly processes the request and returns the expected response. However, the UI is not displaying the output correctly.

import React, { useState } from "react";
import axios from "axios";
import { useDropzone } from "react-dropzone";

interface ExtractedData {
  company: string;
  invoice_date: string;
  items: { description: string; quantity: number; amount: string }[];  // Changed amount to string for "$745.00" format
  total_amount: string;
  practitioner: string;
  patient: string;
  location: string;
  currency: string | null;
  other_details?: string;
}

const ImageUploadOCR: React.FC = () => {
  const [image, setImage] = useState<File | null>(null);
  const [data, setData] = useState<ExtractedData | null>(null);
  const [loading, setLoading] = useState<boolean>(false);

  const { getRootProps, getInputProps } = useDropzone({
    accept: { "image/*": [] },
    onDrop: (acceptedFiles) => setImage(acceptedFiles[0]),
  });

  const handleUpload = async () => {
    if (!image) return;

    setLoading(true);
    const formData = new FormData();
    formData.append("image", image);

    try {
      console.log("Data disk reached");
      const response = await axios.post("http://localhost:5000/api/extract", formData, {
        headers: { "Content-Type": "multipart/form-data" },
      });

      // Log the full response to verify the structure
      console.log("Response data:", response.data);

      // Set data to the state
      setData(response.data);

      // Optionally log company and invoice_date for debugging
      console.log("Company:", response.data?pany);
      console.log("Invoice Date:", response.data?.invoice_date);
    } catch (error) {
      console.error("Error uploading image:", error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div className="p-6 max-w-2xl mx-auto">
      <div {...getRootProps()} className="border-2 border-dashed p-4 cursor-pointer text-center">
        <input {...getInputProps()} />
        {image ? <p><img src={URL.createObjectURL(image)} /></p> : <p>Drag & drop an image, or click to select</p>}
      </div>
      <button className="mt-4 bg-blue-500 text-white px-4 py-2 rounded" onClick={handleUpload} disabled={!image || loading}>
        {loading ? "Processing..." : "Upload & Extract"}
      </button>

      {data && (
        <div className="mt-6">
          <h2 className="text-xl font-bold mb-2">Extracted Data</h2>
          <table className="w-full border-collapse border border-gray-300">
            <thead>
              <tr>
                <th className="border p-2">Field</th>
                <th className="border p-2">Value</th>
              </tr>
            </thead>
            <tbody>
              <tr>
                <td className="border p-2">Company</td>
                <td className="border p-2">{data?pany || "Not available"}</td> {/* Optional chaining added */}
              </tr>
              <tr>
                <td className="border p-2">Invoice Date</td>
                <td className="border p-2">{data?.invoice_date || "Not available"}</td> {/* Optional chaining added */}
              </tr>
            </tbody>
          </table>

          <h3 className="text-lg font-bold mt-4">Items</h3>
          <table className="w-full border-collapse border border-gray-300">
            <thead>
              <tr>
                <th className="border p-2">Description</th>
                <th className="border p-2">Quantity</th>
                <th className="border p-2">Amount</th>
              </tr>
            </thead>
            <tbody>
              {data.items.map((item, index) => (
                <tr key={index}>
                  <td className="border p-2">{item.description}</td>
                  <td className="border p-2">{item.quantity}</td>
                  <td className="border p-2">{item.amount}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </div>
      )}
    </div>
  );
};

export default ImageUploadOCR;

Issue: The API returns the expected result, but the UI does not display the image. No errors are shown in the console.

Backend response:

{'Currency': None, 'Location': '102 Trope Street, New York, NY 45568', 'Other relevant details': {'Due date': '07/30/23', 'Invoice number': '12245', 'Note': 'A prescription has been written out for patient, for an acute throat infection.', 'Subtotal': '$745.00', 'Tax amount': '$157.05', 'Tax rate': '9%'}, 'Patient': 'Kemba Harris', 'Practitioner': 'Dr. Alanah Gomez', 'Total Amount': '$1,902.05', 'company': 'Not specified', 'invoice_date': '07/01/23', 'items': [{'Amount': '$745.00', 'Description': 'Full Check Up', 'Quantity': '1'}, {'Amount': '$1,000.00', 'Description': 'Ear & Throat Examination', 'Quantity': '1'}]}

How can I properly display the image output in the UI? What could be causing the issue?

Share Improve this question edited Feb 16 at 5:30 GoneCase123 asked Feb 16 at 2:45 GoneCase123GoneCase123 4421 gold badge6 silver badges19 bronze badges
Add a comment  | 

4 Answers 4

Reset to default 1

The issue is with mapping your keys , keys are amount, quantity and description but you are trying to get Amount, quantity and Description

{data.items.map((item, index) => (
                <tr key={index}>
                  <td className="border p-2">{item.description}</td>
                  <td className="border p-2">{item.quantity}</td>
                  <td className="border p-2">{item.amount}</td>
                </tr>
              ))}

I tried it sandbox_link

image_output

It should be

{data.['Items or descriptions'].map((item, index) => (
                <tr key={index}>
                  <td className="border p-2">{item.Description}</td>
                  <td className="border p-2">{item.Quantity}</td>
                  <td className="border p-2">{item.Amount}</td>
                </tr>

and i assume your backend is python, js does not have None make it null

try changing

{image ? <p>{image.name}</p> : <p>Drag & drop an image, or click to select</p>}

to

{image ? <p><img src={URL.createObjectURL(image)} /></p> : <p>Drag & drop an image, or click to select</p>}

more info:

https://react-dropzone.js./#:~:text=Preview

https://developer.mozilla./en-US/docs/Web/API/URL/createObjectURL_static

you can set data by doing this

setData(response.data as Unkown as ExtractedData)

发布评论

评论列表(0)

  1. 暂无评论