Home > Software engineering >  Can define type to use with mongodb find().toArray()
Can define type to use with mongodb find().toArray()

Time:11-01

I can't define the correct type for the following function which returns value from mongodb:

export const getPopulatedCountriesByCountryIdsDB = async (countryIds: any[]) => {
    try {
        const query = {
            id: {$in: countryIds}
        }
        const db = await getDb();
        const collectionName = process.env.MONGO_DB_COLLECTION_POPULATED_COUNTRY!;
        const countries = await db?.collection(collectionName).find<Country>(query).toArray();
        return countries;
    } catch (err) {
        logger.error('Error in getPopulatedCountriesByCountryIdsDB:', err);
    }
}

interface Country defined as following:

export interface Country {
    id: ObjectId;
    cities: []
};

I invoke it as following:

  const countries = await getPopulatedCountriesByCountryIdsDB(countriesIds!);

But later, when I try to access some nested properties as following:

const country = countries!.filter((country: any) => country.id === countryId);
const cities = country.cities.filter((city: any) => city.id === cityId);

I get the following error:

Property 'cities' does not exist on type 'Country[]'

How can I properly define the type Country? Thank you!

UPDATE: After remarks from caTS I have updated my code as following:

Country Type:

export interface Country {
    id: ObjectId;
    cities: any[]
};

But get the following error:

Property 'cities' does not exist on type 'Country[]'

UPDATE 1: If I use it without passing the type to this function here:

        const countries = await db?.collection(collectionName).find(query).toArray();

I get the following error:

Property 'cities' does not exist on type 'WithId[]'.

CodePudding user response:

Property 'cities' does not exist on type 'Country[]'

This error arises because you are filtering an array down to one element, and then trying to read a property from that array. Instead you need to take an element from the array and then read the property from the element.

const country = countries!.filter((country: any) => country.id === countryId);

// at this point country is a list containing one element

// read out the first value
const selectedCountry = country[0]

const cities = selectedCountry.cities.filter((city: any) => city.id === cityId);

You will want some error handling in case the array is empty - i.e. if the countryId does not match any country.id.

You will also need to do the same process when working with the selected city.

  • Related