Search code examples
reactjsreact-reduxvite

why is vite.js not rendering any images from my backend api


In my backend I have some restaurants, and when I try mapping them in vite.js it does actually work to render out all of the restaurants, the problem is it just doesn't render any images, I'm new to vite so I'm wondering if it's something to due with my vite.config.js file or if it's something with redux

This is my vite.config.js file

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  server: {
    proxy: {
      "/api": {
        target: "http://127.0.0.1:8000",
        changeOrigin: true,
        secure: false,
      },
    },
    base: "/static/",
  },
});

Here is my redux action

export const listTopRestaurants = () => async (dispatch) => {
  try {
    dispatch({ type: RESTAURANTS_LIST_REQUEST });

    const { data } = await axios.get(`/api/restaurants/most-likes`);

    dispatch({
      type: RESTAURANTS_LIST_SUCCESS,
      payload: data,
    });
  } catch (error) {
    dispatch({
      type: RESTAURANTS_LIST_FAIL,
      payload:
        error.response && error.response.data.message
          ? error.response.message
          : error.message,
    });
  }
};

And here is my jsx code

  const topRestaurantsDetails = useSelector(
    (state) => state.topRestaurantsList
  );
  const { loadingTopRestaurants, error_topRestaurants, topRestaurants } =
    topRestaurantsDetails;

  useEffect(() => {
    dispatch(listTopRestaurants());
    dispatch(listDaySchedule());
  }, [dispatch]);
        <div className="restaurantsContainer">
          {error_topRestaurants ? (
            <h1>{error_topRestaurants}</h1>
          ) : loadingTopRestaurants ? (
            <RenderRestaurantSkeletons showRanking={true} size={160} />
          ) : (
            <>
              {topRestaurants.map((restaurant, index) => {
                return (
                  <RestaurantCard
                    restaurant={restaurant}
                    key={index}
                    index={index}
                    showRanking={true}
                    cardSize={160}
                  />
                );
              })}
            </>
          )}
          <div className="viewAllRestaurantsBtnContainer">
            <Link to="/restaurants" className="viewAllRestaurantsBtn">
              <div className="mainText">Click here to see all restaurants</div>
            </Link>
          </div>
        </div>
function RestaurantCard({ restaurant, index, showRanking, cardSize }) {
  return (
    <Link
      to={`/restaurants/${restaurant.id}`}
      className="restaurantCard"
      style={{ width: cardSize, minWidth: cardSize }}
    >
      <div className="imageContainer">
        <img
          src={restaurant.thumbnail_image}
          alt={restaurant.name}
          className="restaurantImg"
        />
      </div>
      <div className="infoSection">
        {showRanking && <div className="placement">{index + 1}</div>}
        <div className="nameAndLikes">
          <div
            className={`businessName ${
              !showRanking && "businessName__notRanking"
            }`}
          >
            {restaurant.name}
          </div>
          {showRanking && (
            <div className="numLikes">{restaurant.numLikes} likes</div>
          )}
        </div>
      </div>
    </Link>
  );
}

My django backend model

class Restaurant(models.Model):
    thumbnail_image = models.ImageField(null=True)
    name = models.CharField(max_length=55)
    name_spanish = models.CharField(max_length=55)
    numLikes = models.IntegerField(default=0, null=True)
    location = models.CharField(max_length=164, null=True)
    location_spanish = models.CharField(max_length=164, null=True)

    def __str__(self):
        return self.name

I've tried a bunch of different methods of calling the get function to the api but it always has the same problem


Solution

  • So I figured out that Vite automatically fills in the url to a image and adds Vite's localhost url to it, so for example it would say this http://127.0.0.1:5173/images/myimage.png instead of my django api's url (http://127.0.0.1:8000/)

    So what I did is I made a component that will add my django api's url to the image instead

    export function renderImageFromApi(img) {
      return new URL(img, "http://127.0.0.1:8000/").href;
      // For security reasons you should probably hide the url if it's a production app
    }
    

    and then added it to all of my images src

    <img src={renderImageFromApi(eventCard.thumbnail_image)} />