skip to Main Content

.
Hello, with the help of the following code, I try to retrieve a table of "Etablissement" via asynchronous queries. The last line is underlined in red with this message:

Type 'Promise<(string[] | undefined)[]>' is missing the following properties from type 'Establishment[]': length, pop, push, concat, and 29 more.

If anyone has an idea, any suggestions for resolution would be appreciated. Thanks in advance for your help.

Here is a code snippet :

interface GetApplicationHook {
    getApplication: (id?: string) => Promise<ApplicationToSave>
    defaultApplication: ApplicationToSave
    getOneEtablissement: (uai?: string) => Promise<Etablissement>
    toEtablissementsList: (ouList: string[]) => Etablissement[]
}
[...]
const getOneEtablissement = (uai?: string): Promise<Etablissement> => {
        if (uai) {
            return loadOneEtablissement(uai)
                .then((etab: Etablissement) => {
                    return {
                        nom: etab.nom,
                        uai: etab.uai,
                        ou: etab.ou,
                        description: etab.description,
                    }
                })
                .catch(() => Promise.reject("Erreur à la récupération de l'établissement=" + uai))
        }
        return Promise.resolve(defaultEtablissement)
    }

    const fromOuToUai = (ou: string): string => {
        try {
            return ou.split(',')[0].split('=')[1]
        } catch (error) {
            return ou
        }
    }

    const toEtablissementsList = (ouList: string[]): Etablissement[] => {
        const etabList = Promise.all(
            ouList.map(ou => {
                try {
                    const uai = fromOuToUai(ou)
                    getOneEtablissement(uai)
                        .then((data: Etablissement) => data)
                        .catch(() => Promise.reject())
                } catch (error) {
                    return ouList
                }
            })
        )
        return etabList
    }

[...]

I have been looking for information about how Promises work and how to extract the interesting data from them. If I understood correctly, this should be done through the .then() method along with the .catch() method… but that doesn’t seem to be enough here. The problem is about typing apparently but I don’t see where the problem lies.

4

Answers


  1. Chosen as BEST ANSWER

    Here the full component code, if this can help (the attribute listeOrganisations at the bottom needs to be a Etablissement[]) :

    import ApplicationRole from 'domain/ApplicationRole'
    import ApplicationProfile from 'domain/ApplicationProfile'
    import ApplicationToSave from 'domain/ApplicationToSave'
    import useAppsToutaticeService from 'service/AppsToutaticeService'
    import TimeUtils from './TimeUtils'
    import Etablissement from 'domain/Etablissement'
    import useEtablissementService from 'service/EtablissementService'
    
    interface GetApplicationHook {
        getApplication: (id?: string) => Promise<ApplicationToSave>
        defaultApplication: ApplicationToSave
        getOneEtablissement: (uai?: string) => Promise<Etablissement>
        toEtablissementsList: (ouList: string[]) => Etablissement[]
    }
    
    const GetApplication = (): GetApplicationHook => {
        const { loadApp } = useAppsService()
        const { loadOneEtablissement } = useEtablissementService()
    
        const defaultApplication = {
            applicationId: '',
            nom: '',
            description: '',
            categorie: ' ',
            dateFermeture: '',
            dateOuverture: '',
            icone: '',
            statut: '',
            urlConnexion: '',
            urlDeconnexion: '',
            dnmaTypeService: '',
            dnmaCategorie: ' ',
            dnmaUai: '',
            dnmaOutil: ' ',
            listeManagers: [],
            listeExplicitManagers: [],
            listeExplicitMembers: [],
            listeOrganisations: [],
            listeProfils: [],
            listeRoles: [],
        }
    
        const defaultEtablissement = {
            nom: '',
            uai: '',
            ou: '',
            description: '',
        }
    
        const getFirstElementOrDefault = (elements?: string[], defaultValue = '') => {
            if (elements && elements.length > 0) return elements[0]
            return defaultValue
        }
    
        const toApplicationProfile = (profile: string): ApplicationProfile => {
            return {
                dn: profile,
                cn: profile.split(',')[0].split('=')[1],
            }
        }
    
        const toApplicationProfileList = (profileList: string[]): ApplicationProfile[] => {
            if (profileList && profileList.length > 0) {
                return profileList.map(profile => toApplicationProfile(profile))
            }
            return []
        }
    
        const toApplicationRole = (appRole: string): ApplicationRole => {
            return {
                cn: appRole.split(',')[0].split('=')[1],
                dn: appRole,
                nom: '',
                description: '',
                listeProfils: [],
                listeProprietaires: [],
                listeManagers: [],
                listeExplicitManagers: [],
                listeTags: [],
                listeMemberUrl: [],
            }
        }
    
        const toApplicationRoleList = (appRolesList: string[]): ApplicationRole[] => {
            if (appRolesList && appRolesList.length > 0) {
                return appRolesList.map(appRole => toApplicationRole(appRole))
            }
            return []
        }
    
        const { isoToDate } = TimeUtils()
    
        const getOneEtablissement = (uai?: string): Promise<Etablissement> => {
            if (uai) {
                return loadOneEtablissement(uai)
                    .then((etab: Etablissement) => {
                        return {
                            nom: etab.nom,
                            uai: etab.uai,
                            ou: etab.ou,
                            description: etab.description,
                        }
                    })
                    .catch(() => Promise.reject("Erreur à la récupération de l'établissement=" + uai))
            }
            return Promise.resolve(defaultEtablissement)
        }
    
        const fromOuToUai = (ou: string): string => {
            try {
                return ou.split(',')[0].split('=')[1]
            } catch (error) {
                return ou
            }
        }
    
        const toEtablissementsList = (ouList: string[]): Etablissement[] => {
            const etabList = Promise.all(
                ouList.map(ou => {
                    try {
                        const uai = fromOuToUai(ou)
                        getOneEtablissement(uai)
                            .then((data: Etablissement) => data)
                            .catch(() => Promise.reject())
                    } catch (error) {
                        return ouList
                    }
                })
            )
            return etabList
        }
    
        const getApplication = (id?: string): Promise<ApplicationToSave> => {
            if (id) {
                return loadApp(id)
                    .then(app => {
                        return {
                            applicationId: app.applicationId,
                            description: app.description,
                            nom: app.nom,
                            categorie: getFirstElementOrDefault(app.listeCategories, ' ').toLocaleLowerCase(),
                            dateFermeture: isoToDate(app.endTime),
                            dateOuverture: isoToDate(app.startTime),
                            icone: app.icone ?? '',
                            statut: app.statut ?? 'TITI',
                            urlConnexion: app.url ?? '',
                            urlDeconnexion: getFirstElementOrDefault(app.listeUrlLogout),
                            dnmaTypeService: app.dnmaTypeService ?? 'TOTO',
                            dnmaCategorie: app.dnmaCatego ?? ' ',
                            dnmaUai: app.dnmaRne ?? 'TUTU',
                            dnmaOutil: app.dnmaOutil ?? ' ',
                            listeManagers: [],
                            listeExplicitMembers: [],
                            listeExplicitManagers: [],
                            listeOrganisations: toEtablissementsList(app.listeOrganisations),
                            listeProfils: toApplicationProfileList(app.listeProfils),
                            listeRoles: toApplicationRoleList(app.listeRoles),
                        }
                    })
                    .catch(() => Promise.reject("Erreur à la récupération de l'application=" + id))
            }
            return Promise.resolve(defaultApplication)
        }
        return { getApplication, defaultApplication, getOneEtablissement, toEtablissementsList }
    }
    
    export default GetApplication
    
    

  2. The issue with the code is that the toEtablissementsList function is returning a Promise instead of an array of Etablissement objects.

    try this:

    const toEtablissementsList = (ouList: string[]): Promise<Etablissement[]> => {
      return Promise.all(
        ouList.map((ou) => {
          try {
            const uai = fromOuToUai(ou);
            return getOneEtablissement(uai);
          } catch (error) {
            return Promise.reject(error);
          }
        })
      ).then((etabList) => etabList.filter((etab) => !!etab));
    };
    
    Login or Signup to reply.
  3. The issue with the last line of your code is that etabList is a Promise that resolves to an array of Etablissement[], not an array of Etablissement objects. This is because Promise.all() returns a promise that resolves to an array of the resolved values of the input promises.

    You need to modify your toEtablissementsList() function to await the resolution of the Promise.all() call and then return the resulting Etablissement[] array. You can also simplify your code by removing the unnecessary try-catch blocks.

    Something like this:

    const toEtablissementsList = async (ouList: string[]): Promise<Etablissement[]> => {
      const etabListPromises = ouList.map(ou => {
        const uai = fromOuToUai(ou);
        return getOneEtablissement(uai);
      });
    
      const etabList = await Promise.all(etabListPromises);
      return etabList;
    }
    

    you can create an array of Promise<Etablissement> objects by mapping over the ouList array and calling getOneEtablissement() for each uai. Then use Promise.all() to wait for all the promises to resolve, and return the resulting Etablissement[] array.

    Also changed the return type of toEtablissementsList() to Promise<Etablissement[]>, since the function is asynchronous and returns a Promise.

    Edit for request:
    To extract an Etablissement[] from a Promise<Etablissement[]>, you need to wait for the promise to resolve using the await keyword or using the then() method.

    function getEtablissementsList() {
      const ouList = ["ou1", "ou2", "ou3"];
      const etabListPromise = toEtablissementsList(ouList);
      etabListPromise.then(etabList => {
        console.log(etabList); // do something with the Etablissement[] array
      });
    }
    
    getEtablissementsList();
    
    Login or Signup to reply.
  4. Hi and thanks for all your answers,

    I finally used the function suggested by Benji after which I made some other modifications in my code. Here is the final result if it can help anyone.

    Good day to you !

        import ApplicationRole from 'domain/ApplicationRole'
        import ApplicationProfile from 'domain/ApplicationProfile'
        import ApplicationToSave from 'domain/ApplicationToSave'
        import useAppsToutaticeService from 'service/AppsToutaticeService'
        import TimeUtils from './TimeUtils'
        import Etablissement from 'domain/Etablissement'
        import useEtablissementService from 'service/EtablissementService'
        import ApplicationToutatice from 'domain/ApplicationToutatice'
        
        interface GetApplicationHook {
            getApplication: (id?: string) => Promise<ApplicationToSave>
            defaultApplication: ApplicationToSave
        }
        
        const GetApplication = (): GetApplicationHook => {
            const { loadApp } = useAppsToutaticeService()
            const { loadOneEtablissement } = useEtablissementService()
        
            const defaultApplication = {
                applicationId: '',
                nom: '',
                description: '',
                categorie: ' ',
                dateFermeture: '',
                dateOuverture: '',
                icone: '',
                statut: '',
                urlConnexion: '',
                urlDeconnexion: '',
                dnmaTypeService: '',
                dnmaCategorie: ' ',
                dnmaUai: '',
                dnmaOutil: ' ',
                listeManagers: [],
                listeExplicitManagers: [],
                listeExplicitMembers: [],
                listeOrganisations: [],
                listeProfils: [],
                listeRoles: [],
            }
        
            const getFirstElementOrDefault = (elements?: string[], defaultValue = '') => {
                if (elements && elements.length > 0) return elements[0]
                return defaultValue
            }
        
            const toApplicationProfile = (profile: string): ApplicationProfile => {
                return {
                    dn: profile,
                    cn: profile.split(',')[0].split('=')[1],
                }
            }
        
            const toApplicationProfileList = (profileList: string[]): ApplicationProfile[] => {
                if (profileList && profileList.length > 0) {
                    return profileList.map(profile => toApplicationProfile(profile))
                }
                return []
            }
        
            const toApplicationRole = (appRole: string): ApplicationRole => {
                return {
                    cn: appRole.split(',')[0].split('=')[1],
                    dn: appRole,
                    nom: '',
                    description: '',
                    listeProfils: [],
                    listeProprietaires: [],
                    listeManagers: [],
                    listeExplicitManagers: [],
                    listeTags: [],
                    listeMemberUrl: [],
                }
            }
        
            const toApplicationRoleList = (appRolesList: string[]): ApplicationRole[] => {
                if (appRolesList && appRolesList.length > 0) {
                    return appRolesList.map(appRole => toApplicationRole(appRole))
                }
                return []
            }
        
            const { isoToDate } = TimeUtils()
        
            const defaultEtablissement = {
                nom: '',
                uai: '',
                ou: '',
                description: '',
            }
        
            const getOneEtablissement = (uai?: string): Promise<Etablissement> => {
                if (uai) {
                    return loadOneEtablissement(uai)
                        .then((etab: Etablissement) => {
                            return {
                                nom: etab.nom,
                                uai: etab.uai,
                                ou: etab.ou,
                                description: etab.description,
                            }
                        })
                        .catch(() => Promise.reject("Erreur à la récupération de l'établissement=" + uai))
                }
                return Promise.resolve(defaultEtablissement)
            }
        
            const fromOuToUai = (ou: string): string => {
                try {
                    return ou.split(',')[0].split('=')[1]
                } catch (error) {
                    return ou
                }
            }
        
            const toEtablissementsList = async (ouList: string[]): Promise<Etablissement[]> => {
                const etabListPromises = ouList.map(ou => {
                    const uai = fromOuToUai(ou)
                    return getOneEtablissement(uai)
                })
        
                const etabList = await Promise.all(etabListPromises)
                return etabList
            }
        
            const toApplicationToSave = (app: ApplicationToutatice, etabListAsOu: string[]): Promise<ApplicationToSave> => {
                return toEtablissementsList(etabListAsOu)
                    .then(etabList => {
                        return {
                            applicationId: app.applicationId,
                            description: app.description,
                            nom: app.nom,
                            categorie: getFirstElementOrDefault(app.listeCategories, ' ').toLocaleLowerCase(),
                            dateFermeture: isoToDate(app.endTime),
                            dateOuverture: isoToDate(app.startTime),
                            icone: app.icone ?? '',
                            statut: app.statut ?? 'TOTO',
                            urlConnexion: app.url ?? '',
                            urlDeconnexion: getFirstElementOrDefault(app.listeUrlLogout),
                            dnmaTypeService: app.dnmaTypeService ?? 'TITI',
                            dnmaCategorie: app.dnmaCatego ?? ' ',
                            dnmaUai: app.dnmaRne ?? 'TUTU',
                            dnmaOutil: app.dnmaOutil ?? ' ',
                            listeManagers: [],
                            listeExplicitMembers: [],
                            listeExplicitManagers: [],
                            listeOrganisations: etabList,
                            listeProfils: toApplicationProfileList(app.listeProfils),
                            listeRoles: toApplicationRoleList(app.listeRoles),
                        }
                    })
                    .catch(() => Promise.reject())
            }
        
            const getApplication = (id?: string): Promise<ApplicationToSave> => {
                if (id) {
                    return loadApp(id)
                        .then(app => {
                            return toApplicationToSave(app, app.listeOrganisations)
                        })
                        .catch(() => Promise.reject("Erreur à la récupération de l'application=" + id))
                }
                return Promise.resolve(defaultApplication)
            }
        
            return { getApplication, defaultApplication }
        }
        
        export default GetApplication```
    
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search