skip to Main Content

I need to fetch all the user libraries from the backend and display them in a dropdown menu.

I created a separate JS file to fetch the libraries from the backend, and then called that JS file in my main library TSX page.

This was the error that occurred:

Type ‘Promise<{ label: string; value: string; }[] | undefined>’ is
missing the following properties from type ‘({ label: any; } & {
value: any; })[]’: length, pop, push, concat, and 35 more

fetch_libraries JS file (Fetches the libraries from the backend):

import { getItemFor } from './async_store';
import { supabase } from './supabase';

// Supabase is the backend I'm using.

export default async function libraries_fetch () {
    
    // Creating empty array and fetching user email
    const libraries = [];
    const email = await getItemFor("email");

    // Fetching libraries from the database
    const { data, error } = await supabase
        .storage
        .from('pdfs')
        .list(`${email}/books`);
    
    // Adding libraries to the libraries array
    if (data != null) {
        for (let x = 0; x < data.length; x ++) {
            libraries.push({label: data[x].name, value: x.toString()})
        }
        return (libraries);
    };
};

My libraries main page. I’m trying to get a dropdown menu on the header’s top right corner.

// Expo 
import Ionicons from '@expo/vector-icons/Ionicons';
import { Stack } from 'expo-router';
import { Dropdown } from 'react-native-element-dropdown';

// App Backend
import { styles } from '../../assets/stylers';
import Colors from '@/constants/Colors';
import fetch_libraries from '../backend/fetch_libraries';

// React
import { View } from 'react-native';


export default function library() {
    const data = fetch_libraries()
    return (
    <View>
        <Stack.Screen 
        options={
            {
                headerStyle: styles.HeaderStyle, 
                headerTitleStyle: styles.HeaderTextStyle, 
                headerRight:(() => <Dropdown
                                     style={styles.libraryDropDownScroll}
                                     itemContainerStyle={styles.libraryDropDownItem}
                                     containerStyle={styles.libraryDropDownContainer}
                                     data={data} // This is where the error is occurring
                                     labelField="label"
                                     valueField="value"
                                     placeholder='Main'
                                     onChange={item => {}}
                                     renderRightIcon={() => (<Ionicons 
name="arrow-down" 
                                                               size={20} 
color={Colors.black} 
style={styles.closeIconStyle}/>)}
                                   />)}}/>
      </View>
        );
    };

I was experimenting around with useState and useEffect but I can’t seem to get the desired outcome. If I use useState, it doesn’t update the libraries list in the first render, so the array is still blank when the app opens.

2

Answers


  1. you should use await before fetch_libraries().

    const [data, setData] = useState([])
    
    useEffect(() => {
        const fetchData = async () => {
            const response = await fetch_libraries()
            setData(response)
        }
    
        fetchData()
    },[])
    
    Login or Signup to reply.
  2. As @monvanCe suggests, using await will help.

    However, it would be better to use a custom hook which will fetch this data when the component mounts and return the result.

    For instance:

    export const useData = () => {
      const [data, setData] = useState([]);
      useEffect(() => {
      // fetch data here and set it in state
      }, []);
      
      return data;
    }
    

    You can then call this hook in your header component to get the data.

    import {useData} from '...'
    
    
    const dropDownData = useData();
    return (
    ...
      <Dropdown 
        data={dropDownData}
      />
    ...
    )
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search