Load images dynamically based on their filenames

As I continue to learn, I am working on a delivery layout project. I have come across a section where I need to load Cards with restaurant information. The names are displaying correctly, but I am facing issues with loading the images. I am using a JSON file with a 'restaurants' type, which includes id, name, and image.

Here is the file structure:

/
|--/src
     |--/App
     |    |--index.tsx
     |--/components
     |    |--/restaurants
     |         |--index.tsx
     |         |--/restaurantCard
     |              |--index.tsx
     |--/assets
          |--/restaurants
               |--all images png

The RestaurantCard Component:

import { View, Text, Pressable, Image } from 'react-native'

import { RestaurantsProps } from '..'
import { FontAwesome, Ionicons } from '@expo/vector-icons'


export default function RestaurantCard({ item }: { item: RestaurantsProps }) {

    const width = 140; 
    const height = 100;

    // This line works
    const Logo = Image.resolveAssetSource(require(`@/src/assets/restaurants/kfc.png`)).uri

    // This doesn't work
    // const Logo = Image.resolveAssetSource(require(`@/src/assets/restaurants/${item.image}`)).uri

    return (
        <Pressable style={{
            marginVertical: 4,
            justifyContent: 'center',
            alignItems: 'center',
            backgroundColor: '#c8c8c8',
            borderRadius: 16,
        }}
            onPress={() => { console.log(`CLICOU EM ${item.name}`) }}
        >
            <View style={{
                width: width,
                height: height,
                backgroundColor: 'black',
                borderRadius: 16,
            }}>
                <Image source={{uri: Logo}} style={{
                    width: width,
                    height: height,
                    resizeMode: 'stretch',
                    borderRadius: 16,
                }} />
            </View>
            <FontAwesome name='circle' size={38} color={'#aaa'} style={{
                position: 'absolute',
                bottom: 26,
            }} />
            <Ionicons name='fast-food-outline' size={24} style={{
                position: 'absolute',
                bottom: 32,
                color: '#ddd'
            }} />
            <Text className='font-semibold text-gray-600 text-lg mt-5'>{item.name}</Text>
        </Pressable>
    )
}

The Restaurant list component:

import { useEffect, useState } from 'react'
import { View, FlatList } from 'react-native'
import RestaurantCard from './restaurantCard';

import * as restaurantesJson from '@/db.json'

export interface RestaurantsProps {
    id: string;
    name: string;
    image: string
}

export function Restaurants({ urlFetch }: { urlFetch: string }) {

    const [restaurants, setRestaurants] = useState<RestaurantsProps[]>([])

    useEffect(() => {
        //This async function was an attempt, but nothing changed
        async function getRestaurantsJson() {
            // console.log(data);
            setRestaurants(restaurantesJson.restaurants); 

            console.log(restaurants);
        }

        getRestaurantsJson()
    }, []);

    return (
        <View>
            <FlatList
                horizontal={true}
                data={restaurants}
                renderItem={({ item }) => <RestaurantCard item={item} />}
                showsHorizontalScrollIndicator={false}
                contentContainerStyle={{
                    gap: 12,
                    justifyContent: 'center',
                    alignItems: "center"
                }}
            />
        </View>
    )
}

I am currently seeking a solution that automatically loads the images without requiring manual file exports.

Answer №1

There is a unique way to tackle these problems

Reminder: It's important for your RestaurantsProps image name to match the local assets image name

For example: Store all images in a local array like this

const img = {
"kfc.png": require('@/src/assets/restaurants/kfc.png'),
  "mcdonalds.png": require('@/src/assets/restaurants/mcdonalds.png'),
.....,
}
 ..

const logo = img[item.image]

<Image source={Logo}>

Answer №2

If you're facing an issue, it could be due to the limitation of dynamic imports using require() in React Native when working directly with variables.

One way to address this is by creating a workaround where you preload the images into an object that associates image filenames with require statements. Below is an example of how you can accomplish this:

const images: { [key: string]: any } = {
"kfc": require('@/src/assets/restaurants/kfc.png'),
"burgerking": require('@/src/assets/restaurants/burgerking.png'),
"mcdonalds": require('@/src/assets/restaurants/mcdonalds.png'),
//Include other images here
}

Additionally, below is the code for the RestaurantCard component :

export default function RestaurantCard({ item }) {
const width = 140; 
const height = 100;

// Dynamically fetch the image from the images object
const Logo = Image.resolveAssetSource(images[item.image]).uri;

return (
    <Pressable style={{ marginVertical: 4, justifyContent: 'center', alignItems: 'center', backgroundColor: '#c8c8c8', borderRadius: 16 }}
        onPress={() => console.log(`Clicked on ${item.name}`)}>
        <View style={{ width: width, height: height, backgroundColor: 'black', borderRadius: 16 }}>
            <Image source={{uri: Logo}} style={{ width: width, height: height, resizeMode: 'stretch', borderRadius: 16 }} />
        </View>
        <FontAwesome name='circle' size={38} color={'#aaa'} style={{ position: 'absolute', bottom: 26 }} />
        <Ionicons name='fast-food-outline' size={24} style={{ position: 'absolute', bottom: 32, color: '#ddd' }} />
        <Text className='font-semibold text-gray-600 text-lg mt-5'>{item.name}</Text>
    </Pressable>
);
}

Remember to ensure that the image field in your JSON data exactly matches the filenames in the object, for example: "kfc"

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for overcoming the Chrome Extension Error related to the "script-source 'self'" issue

I've been developing a Chrome extension that uses goo.gl to shorten URLs. Here is the code I'm currently working with: $("#ajaxfiller").text(""); //Retrieve entered URL var longUrl = $("#input2").val(); longUrl = '"' + longUrl + &a ...

Encountering an Android error while attempting to populate a ListView with JSON data using PHP, JSON, and Java

I am currently working on developing a search feature for my Android application using PHP, JSON, and SQL. Below is the code snippet that is causing me trouble: try{ JSONArray jArray = new JSONArray(result); int jArrLeng = jArray.length ...

How to Retrieve Information from JSON Files?

I am trying to extract the username from a specific Json URL. Although I have the following code, it is unfortunately throwing a JSON parsing error message: Json parsing error Below is the code snippet: HttpHandler.java public class HttpHandler { ...

Enigmatic Cartography Classification

In my attempt to construct a specialized Map-like class that maps keys of one type to keys of another, I encountered a challenge. A straightforward approach would be to create a Map<keyof A, keyof B>, but this method does not verify if the member typ ...

Distinguishing Literal and Parameterized Routes in Angular 6

I've encountered a strange issue that I'm not sure how to handle. In my application, you can either view your public account or create a new one. The Account and CreateAccount modules are standalone and lazy loaded in the routes.ts file. export ...

What is the method to ensure that the children of an object strictly adhere to a specific interface or inherit from it?

Is there a way to ensure that an interface extends from another interface in TypeScript? For example: export interface Configuration { pages: { home: IHome; about: IAbout; // How can we make IAbout extend IPage? contact: IPage; }; } inte ...

Make sure to implement validations prior to sending back the observable in Angular

Each time the button is clicked and if the modelform is invalid, a notification message should be returned instead of proceeding to create a user (createUser). The process should only proceed with this.accountService.create if there are no form validation ...

The React Nested Loop Query: Maximizing Efficiency in Data

Learning React has been a challenge for me, especially when comparing it to XML/XPath. In this scenario, I have two arrays simplified with basic string properties... customerList: Customer[] export class Customer { id: string = ""; firstnam ...

Convert the xs:choice construct into a JSON schema

Trying to grasp the concept of JSON Schema's oneOf. I am working on converting an XML format into a JSON version and need a JSON schema to validate the key aspects (acknowledging there will be variations). I have developed an XML Schema structure wh ...

Exploring the dynamic capabilities of JSON with ASP .Net

After successfully retrieving JSON data from a database using PHP through json_encode() and jQuery parsing, I'm curious if there is a similar method for accomplishing this dynamically in ASP.Net Web Forms. Specifically, without the need to pre-determi ...

Verification of custom data type validation

I am puzzled by the behavior of this custom type state: interface DataType { [key: string]: string;} const [data, setData] = React.useState<DataType>({}); When I attempt to execute console.log(data === {}) It surprisingly returns false. Why ...

Error encountered when attempting to insert data into a PostgreSQL database using Node.js and Sequelize

I'm currently using the node sequelize library to handle data insertion in a postgress database. Below is the user model defined in the Users.ts file: export class User extends Sequelize.Model { public id!: number; public name: string; public ...

The React component using createPortal and having its state managed by its parent will remain static and not refresh upon state modifications

I am facing a problem that can be seen in this live example: https://stackblitz.com/edit/stackblitz-starters-qcvjsz?file=src%2FApp.tsx The issue arises when I pass a list of options to a radio button list, along with the state and setter to a child compon ...

Encountering error "Django object cannot be serialized to JSON"

I ran into an issue with my webservice where it was throwing a unicodeEncodeError exception when trying to read a JSON object. Upon some research, I stumbled upon a useful post on How to convert a dictionary to a Unicode JSON string? (Despite following ad ...

`The challenge with interpreting a BufferedReader entity`

I am looking for a solution to read the output of a BufferedReader object in JSON format, parse the JSON, and extract specific values. The code I currently have is: BufferedReader reader = new BufferedReader(new InputStreamReader(proc1.get ...

Creating an interface for a class instance through the implementation of a class constructor

I am working on an application where developers can specify which component they want to render a certain part. I need users to understand that they must implement an interface, but I'm struggling with correctly writing the typing. export interface I ...

Tips for showcasing a blurry image in NextJS while it's in the process of being fetched?

Is there a way to achieve a similar effect like the one showcased below? https://i.sstatic.net/9unuN.gif I've managed to do something similar with Gatsby, but I'm curious if it's achievable with NextJS as well. ...

What is the best way to search for and sort through the data in this particular scenario?

This code snippet is specifically created for extracting and comparing data from the Google spreadsheet shown in the images. exports.processosjudiciais = functions.https.onRequest(async (request, response): Promise<any> => { const jwtClient = ...

VueD3tree successfully fetches data, however, it is not being displayed on the screen

Just started delving into Vue and VueD3tree. Attempting to display a tree using the vued3tree library with data pulled from an API. Strangely enough, when trying with static data, the tree displays perfectly fine. However, when fetching data dynamically, a ...

Encountering unusual JSON formatting when using the HTTP GET method with Node.js/Express

Currently, I am facing an issue with parsing data from keepa API as it returns a JSON format that standard JSON parsers cannot handle. Surprisingly, when I make the same request in Postman, the response is a readable JSON. Can someone help me figure out ...