IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

TypeScript Discussion :

Typer une fonction useQuery()


Sujet :

TypeScript

  1. #1
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 214
    Par défaut Typer une fonction useQuery()
    Bonjour à tous,

    Je vais essayé d'être le plus claire possible. Je développe une App iOS/Android avec React Native et Type Script.
    En partant de zéro, j'ai tout appris avec le Web et Youtube.

    Grâce à un tuto, j'ai pu faire une fonction (solution 1) qui va faire appelle à useQuery pour extraire les données d'un base de donnée, le tout typé.
    J'utilise cette fonction sur trois vues. Ces trois font appelle à cette fonction et le paramètre queryKey est le même pour ces trois vues

    Pour un besoin, j'utilise réutilisé directement la fonction useQuery() (solutiuon 2)pour que je puisse paramètre queryKey pour une vue.
    Mon problème est que je n'ai pas réussi à typer ma sortie....

    Pour être plus précis, je vous montre la solution 1, afin de mieux comprendre ma question

    Dans ma vue setting.tsx, j'ai ceci

    Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    import { useFetchQuery } from "@/hooks/useFetchQuery";
    const {data, isFetching} = useFetchQuery("/getsettings/[id_field]/[id_user]", {id_field: 0, id_user:id_user})

    Dans mon fichier useFetchQuety.ts, j'ai ceci

    Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    import { useInfiniteQuery, useQuery } from '@tanstack/react-query'
     
    const endpoint = "https://api.web.ch/dashboard"
     
    type API = {
    '/getsettings/[id_field]/[id_user]': {
            response: number, 
            id_field: number,
            method: string,
            fields:{
                id_field: number,
                field_name: string,
                field_longname: string,
                field_city: string,
                field_lat: number,
                field_lng: number
            }[],
            settings: {
                id_station_type?: number,
                station_type_name: string,
                station_type_awe?: string,
                field_data: {
                    id_field: number,
                    field_name: string,
                    field_user_role: number,
                    station_data: {
                        id_station: number,
                        station_name: string,
                        station_longname: string,
                        station_type_awe: string,
                        station_archive: number,
                        station_lat: number,
                        station_lng: number,
                        station_alt: number,
                        sensors_data: {
                            id_sensor: number,
                            sensor_active: number,
                            sensor_name: string,
                            sensor_unit: string,
                            sensor_longname: string,
                            id_sensor_type: number,
                            sensor_type_name: string,
                            sensor_type_longname: string,
                            sensor_type_awe: string,
                            sensor_chart_style: string,
                            sensor_chart_borderWidth: string,
                            sensor_chart_pointRadius: number,
                            sensor_chart_showLine: number,
                            sensor_chart_fill: number,
                            sensor_chart_borderColor: string,
                            sensor_chart_backgroundColor: string,
                            sensor_chart_pointStyle: string,
                            sensor_threshold_operator:'string',
                            sensor_threshold_min: number,
                            sensor_threshold_max: number,
     
                        }[],
                    }[],
                }[],
            }[],
        }
    }
     
    export function useFetchQuery<T extends keyof API>(path: T, params?: Record<string, string | number>){
        const localurl = endpoint + Object.entries(params ?? {}).reduce((acc, [key, value]) => acc.replaceAll(`[${key}]`, value.toString()) as T, path)
     
        //console.log("useFetchUqrey: ",localurl)
     
        return useQuery({
            queryKey: [localurl],
            //refetchIntervalInBackground: true,  
            //refetchInterval: 60000, // 60 000 ms = 60 secondes
            //refetchOnWindowFocus: false,
            //staleTime:30000,
            queryFn: async () => { // Comment on reécupère les résultat
                //await wait(2);
                return fetch(localurl,{
                    headers:{
                        Accept: 'application/json',
                    }
                }).then((r) => r.json() as Promise<API[T]>); // Convertir le résultat (r) en json
            },
        })
    }

    Le mega avantage, est que
    Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    const {data, isFetching} = useFetchQuery("/getsettings/[id_field]/[id_user]", {id_field: 0, id_user:id_user})

    lorsque je saisi data. , après le point il me propose toutes les possiblités qui sont défini dans API.

    Solution 2
    Dans la solution 2, je le fais différemment. Dans ma vue [id].tsx, j'ai

    Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    const {data, isPaused, isLoading, error, refetch, isFetching}= useQuery({ // Min 52 https://www.youtube.com/watch?v=bpHq_-bPkGo
            queryKey: ['station', params.id, dateRange],
            queryFn: () => fetchStation(params.id, dayjs(dateRange.startDate).format("YYYY-MM-DD"), dayjs(dateRange.endDate).format("YYYY-MM-DD"), id_user),
            //retryOnMount: false,
            refetchInterval: 30000,
            //gcTime: 1000 * 60,
            //staleTime: 1000 * 30, // Data remains fresh for 60 sec
            refetchOnWindowFocus: true,
            //enabled: false,
            //retry: 2, // Retry twice on failure
            //retryDelay: 2000, // Wait 2 seconds between retries
            //select: (data) => data.map((post) => post.title), // Extract only post title
        })
    Comme vous pouvez le voir, je peux directement paramètrer useQuery.

    Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
     
    import { QueryClient, useInfiniteQuery, useQuery } from '@tanstack/react-query'
     
    const uri = "https://api.web.ch/dashboard"
    const endpoint = "/getstation/"
    const params = "/"
     
    const headers = {
        accept: 'application/json',
        Authorisation: 'key',
    }
     
    export const fetchStation = async (id:string, dateFrom:string, dateTo:string, user_id:number) => {
     
        const url = uri+endpoint+id+'/'+dateFrom+'/'+dateTo+'/'+user_id+'/';
        const options = {
            method: 'GET',
            headers,
        };
     
        try {
            const res = await fetch(url, options);
            /*
            if(!res.ok){
               throw new Error('[fetchQuery] Failed to fetch a s tation') 
            }
            */
            const json = await res.json();
            return json;
     
        }catch(err){
            console.error('[fetchQuery] ' + err);
        }
     
    };
    queryFn fait appelle à la fonction fetchStation() qui va s'occuper de faire la requête sur ma base de données.

    cela fonctionne très bien, sauf que, ... dans la solution deux, je n'ai pas de typage. Docn si je fais

    data. , après le point j'ai pas d'option. Tout cela, parce que je n'ai pas comme dans la solution 1, le API, genre

    Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
     
    type API = {
    '/getsettings/[id_field]/[id_user]': {
            response: number, 
            id_field: number,
            method: string,
            fields:{
                id_field: number,
                field_name: string,
                field_longname: string,
                field_city: string,
                field_lat: number,
                field_lng: number
            }[],
            settings: {
                id_station_type?: number,
                station_type_name: string,
                station_type_awe?: string,
                field_data: {
                    id_field: number,
                    field_name: string,
                    field_user_role: number,
                    station_data: {
                        id_station: number,
                        station_name: string,
                        station_longname: string,
                        station_type_awe: string,
                        station_archive: number,
                        station_lat: number,
                        station_lng: number,
                        station_alt: number,
                        sensors_data: {
                            id_sensor: number,
                            sensor_active: number,
                            sensor_name: string,
                            sensor_unit: string,
                            sensor_longname: string,
                            id_sensor_type: number,
                            sensor_type_name: string,
                            sensor_type_longname: string,
                            sensor_type_awe: string,
                            sensor_chart_style: string,
                            sensor_chart_borderWidth: string,
                            sensor_chart_pointRadius: number,
                            sensor_chart_showLine: number,
                            sensor_chart_fill: number,
                            sensor_chart_borderColor: string,
                            sensor_chart_backgroundColor: string,
                            sensor_chart_pointStyle: string,
                            sensor_threshold_operator:'string',
                            sensor_threshold_min: number,
                            sensor_threshold_max: number,
     
                        }[],
                    }[],
                }[],
            }[],
        }
    }

    ma question


    J'ai aucune idée, comment je peux adapter la solution 2, pour appliquer le typage, comme dans la solution 1, de manière simple.
    La solution 1, je l'ai écris en suivant un tuto, et ca me semble complique

    Auriez-vous la gentillesse de me guider et m'aider à modifier/adapter la solution 2 pour ajouter le typage?

    je vous remercie et je vous souhaite uen bonne année

  2. #2
    Membre expérimenté
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Mai 2005
    Messages : 3 214
    Par défaut
    J'ai essayé un truc qui semble fonctionner, mais je ne suis vraiment pas sûre...

    dans ma vue [id].tsx, j'ai ajouté ceci

    Code typescript : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
     
    type STA = {
        response: number, 
        id: number,
        method: string,
        next: string | null,
        fields: {
            id_field: number,
            field_name: string,
            field_longname: string,
            field_city: string,
            field_lat: number,
            field_lng: number
        }[],
        stations: {
            id_field: number,
            field_name: string,
            id_station: number,
            station_longname: string,
            station_type_awe: string,
            id_station_type: number,
            station_type_name: string,
            station_archive: number,
            lat: number,
            lng: number,
            alt: number,
            measures: {
                datasets: {
                    data:{
                        value: number,
                        label: string,
                        date: string,
                        dataPointText: number
                    }[],
                    label: string,
                    showLine:boolean,
                    borderColor:string,
                    backgroundColor:string,
                    pointStyle:string,
                    fill:boolean,
                    borderWidth:number,
                    pointRadius:number,
                    type:string,
                },
                labels: {}[],
                unit: string,
                chartContainer: string,
                id_sensor_type: number,
                id_sensor:number,
                sensor_type: string,
                sensor_type_longname: string,
                sensor_type_awe: string,
            }[],
            measures_found: number,
            station_found: number,
            latest_measure: string,
        }[],
        map_center:{
            lat: number,
            lng: number,
        },
    }
     
    // et j'ai ajouté <STA>
     
    const {data, isPaused, isLoading, error, refetch, isFetching}= useQuery<STA>({ // Min 52 https://www.youtube.com/watch?v=bpHq_-bPkGo
            queryKey: ['station', params.id, dateRange],
            queryFn: () => fetchStation(params.id, dayjs(dateRange.startDate).format("YYYY-MM-DD"), dayjs(dateRange.endDate).format("YYYY-MM-DD"), id_user),
            // https://tanstack.com/query/latest/docs/framework/react/reference/useQuery?from=reactQueryV3
            //retryOnMount: false,
            refetchInterval: 30000,
            //gcTime: 1000 * 60,
            //staleTime: 1000 * 30, // Data remains fresh for 60 sec
            refetchOnWindowFocus: true,
            //enabled: false,
            //retry: 2, // Retry twice on failure
            //retryDelay: 2000, // Wait 2 seconds between retries
            //select: (data) => data.map((post) => post.title), // Extract only post title
        })

    Est-ce que cela vous semble propre et juste ???

Discussions similaires

  1. Réponses: 5
    Dernier message: 28/02/2008, 15h35
  2. Typer paramètres d'une fonction ?
    Par guitou12 dans le forum Langage
    Réponses: 9
    Dernier message: 21/07/2006, 15h00
  3. [VBA-E] avec une fonction value
    Par laas dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 28/11/2002, 14h22
  4. [Turbo Pascal] Allocation et désallocation de pointeurs dans une fonction
    Par neird dans le forum Turbo Pascal
    Réponses: 13
    Dernier message: 17/11/2002, 21h14
  5. Une fonction avec des attributs non obligatoires
    Par YanK dans le forum Langage
    Réponses: 5
    Dernier message: 15/11/2002, 14h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo