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
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)} />