reactjsdjangodjango-rest-frameworkreact-tsxreact-image

Django+DjangoRestFramework+React(TS): React-Image component showing my images' size as 1295x0


In Django; I have Group, Class, Model and Product as, well, models. These are in a hierarchy of Group{Class{Model{Product}}}. So I made dropdowns which works like:

  Group Checkbox
  |-Inner Classes of Selected Group
    |-Inner Models of Selected Class
      |-Inner Products of Selected Model
  (<Image> element here)

The Product models has an image field, which is returned succesfully from the response.json.

I can open the image files, e.g. http://localhost:8000/media/images/p1111.png. Its width is smaller than 1295px and its height is bigger than 0px, ofc.

But in website it does not show.

Then I open Chrome DevTools. Component is there, in component's source code <div>s and <img> are there, but image's size is shown as 1295x0. I open image url, it's smth like, 256x256. I can (of course) make image width 500x500 using CSS, but what if the use inputs an image with different image ratio and size? That will make it look worse or make the image show partially, so both possibilities are bad. So, can I solve it by changing the React part? Or I'm gonna write a function to Django part?

index.tsx:

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: «they even banned shortened urls in TSX COMMMANDS? WTH???»
reportWebVitals();

App.tsx:

import React from "react";
import { Group, Class, Model, Product } from "./components/Group";
import './App.css';

function App() {
  return (
    <div className="App">
      <div className="App-header">
        <br/>
        <span className="header">The Main Page</span>
        <br/><br/>
        <Group />
        <Class />
        <Model />
        <Product />
      </div>
    </div>
  );
}

export default App;

components/Group.tsx:

import React,{useState,useEffect} from "react";
import ReactDOM from "react-dom"
import {createRoot} from "react-dom/client"
import Select from "react-select";
import {Image} from "react-native"

let GROUP:any=null
let CLASS:any=null
let MODEL:any=null

export function Group(props: {}){
    const [ groups, setGropus ] = useState<any[]>([]);
    const [ groupsel, setGroupSel ] = useState("0")
    GROUP=groupsel
    const serviceUrl = 'http://localhost:8000/app/groups/';

    let groupopt:any[]=[]
    groups.map((value:any)=>{
      groupopt.push({value:value.id,label:value.groupName})
    })

    useEffect(()=>{
        var myHeaders = new Headers();
        myHeaders.append("Content-Type", "application/json");
        myHeaders.append("Authorization", "Basic X19tZF9fOjE1OTk1MW15");

        var urlencoded = new URLSearchParams();
        urlencoded.append("groupName", "Sample");

        var requestOptions:RequestInit = {
          method: 'GET',
          headers: myHeaders,
          redirect: 'follow'
        };

        fetch(serviceUrl, requestOptions)
          .then(response => response.json())
          .then(result => setGropus(result))
          .catch(error => console.log('error', error));
    }, [])
    /*
    return (
        <select id="group" onChange={reloadAll}>
          {
            groups.map((value:any) => {
                return (
                    <option value={value.id} key={value.id}>
                        {value.groupName}
                    </option>
                )
            })
          }
        </select>
    )
    */
   return (
    <Select id="group" defaultValue={groupopt[0]} options={groupopt} onChange={(event:any)=>{setGroupSel(event?.value);}}></Select>
   )
}

export function Class(props: {}){
    const [ classes, setClasses ] = useState<any[]>([]);
    const [ classsel, setClassSel ] = useState("0");
    const serviceUrl = 'http://localhost:8000/app/groups/'+GROUP+'/classes/';
    CLASS=classsel
    //console.log(GROUP)

    let classopt:any[]=[]
    classes.map((value:any)=>{
      classopt.push({value:value.id,label:value.className})
    })

    useEffect(()=>{
        var myHeaders = new Headers();
        myHeaders.append("Content-Type", "application/json");
        myHeaders.append("Authorization", "Basic X19tZF9fOjE1OTk1MW15");

        var urlencoded = new URLSearchParams();
        urlencoded.append("className", "Sample");

        var requestOptions:RequestInit = {
          method: 'GET',
          headers: myHeaders,
          redirect: 'follow'
        };

        fetch(serviceUrl, requestOptions)
          .then(response => response.json())
          .then(result => setClasses(result))
          .catch(error => console.log('error', error));
    }, [classes,classopt,classsel,classopt])
    /*
    return (
        <select id="class">
          {
            classes.map((value:any) => {
                return (
                    <option value={value.id} key={value.id}>
                        {value.className}
                    </option>
                )
            })
          }
        </select>
    )
    */
    return (
      <Select id="class" defaultValue={classopt[0]} options={classopt} onChange={(event:any)=>{setClassSel(event.value);}}></Select>
    )
}

export function Model(props: {}){
    const [ models, setModels ] = useState<any[]>([]);
    const [ modelsel, setModelSel ] = useState("0");
    const serviceUrl = 'http://localhost:8000/app/classes/'+CLASS+"/models/";
    MODEL=modelsel

    let modelopt:any[]=[]
    models.map((value:any)=>{
      modelopt.push({value:value.id,label:value.modelName})
    })

    useEffect(()=>{
        var myHeaders = new Headers();
        myHeaders.append("Content-Type", "application/json");
        myHeaders.append("Authorization", "Basic X19tZF9fOjE1OTk1MW15");

        var urlencoded = new URLSearchParams();
        urlencoded.append("modelName", "Sample");

        var requestOptions:RequestInit = {
          method: 'GET',
          headers: myHeaders,
          redirect: 'follow'
        };

        fetch(serviceUrl, requestOptions)
          .then(response => response.json())
          .then(result => setModels(result))
          .catch(error => console.log('error', error));
    }, [models,modelopt,modelsel,modelopt])
    /*
    return (
        <select id="model">
          {
            models.map((value:any) => {
                return (
                    <option value={value.id} key={value.id}>
                        {value.modelName}
                    </option>
                )
            })
          }
        </select>
    )
    */
    return (
      <Select id="model" defaultValue={modelopt[0]} options={modelopt} onChange={(event)=>{setModelSel(event?.value);}}></Select>
    )
}

export function Product(props: {}){
    const [ products, setProducts ] = useState<any[]>([]);
    const [ productsel, setProductSel ] = useState("0");
    const [ productimg, setProductImg ] = useState("http://localhost:8000/media/images/p1111.png");
    const serviceUrl = 'http://localhost:8000/app/models/'+MODEL+'/products/';

    let productopt:any[]=[]
    products.map((value:any)=>{
      productopt.push({value:value.id,label:value.productName,trustedImg:value.trustedImg})
    })

    useEffect(()=>{
        var myHeaders = new Headers();
        myHeaders.append("Content-Type", "application/json");
        myHeaders.append("Authorization", "Basic X19tZF9fOjE1OTk1MW15");

        var urlencoded = new URLSearchParams();
        urlencoded.append("productName", "Sample");

        var requestOptions:RequestInit = {
          method: 'GET',
          headers: myHeaders,
          redirect: 'follow'
        };

        fetch(serviceUrl, requestOptions)
          .then(response => response.json())
          .then(result => setProducts(result))
          .catch(error => console.log('error', error));
    }, [products,productopt,productsel,productimg])
    /*
    return (
        <select id="product">
          {
            products.map((value:any) => {
                return (
                    <option value={value.id} key={value.id}>
                        {value.productName}
                    </option>
                )
            })
          }
        </select>
    )
    */
    return (
      <>
        <Select id="product" defaultValue={productopt[0]} options={productopt} onChange={(event)=>{setProductSel(event?.value);setProductImg("http://localhost:8000"+event?.trustedImg)}}></Select>
        <Image id="image" source={{uri:productimg}} style={{width:"500px",height:"500px"}}/>
      </>
    )
}

/*
function reloadAll(){
  document.getElementById("group")?.remove()
  document.getElementById("class")?.remove()
  document.getElementById("model")?.remove()
  document.getElementById("product")?.remove()
  let root:any=createRoot(document.getElementsByTagName("header")[0])
  root.render(<Group/>)
  root.render(<Class/>)
  root.render(<Model/>)
  root.render(<Product/>)
}
*/

I tried with <img>, but it does not reload the image, so I'm using <Image> from react-image now. I tried width:500px,height:500px but we both know that this is a temporary and would not work if user adds another Product object with image.

So yeah. I thought "what you get in URL is what you get in Website", but again the frontend world seemed to fail me.


Solution

  • Welp, I was using react-native. That's why. It's a module for... mostly mobile devices. I put an <img> instead and now it works.