Skip to content

@pinia/colada: use defineQueryOptions() for reactive options #2597

@lysz210

Description

@lysz210

Description

Ref properties doesn't trigger refresh, and the key isn't updated.

<template>
    <v-container>
        <v-autocomplete
            label="Select"
            :items="gpxFiles.data"
            v-model="selectedGpxFile"
        ></v-autocomplete>
        <p>{{ gpxInfoEnabled ? 'enabled' : 'disabled' }}</p>
        <p>{{ selectedGpxFile }}</p>
        <p>{{ gpxData.data?.uid }}  {{ gpxData.data?.name }}</p>
        <p>{{ gpxData.data?.timestamp }}</p>
        <p>{{ gpxData.data?.points?.length }}</p>
    </v-container>
</template>

<script lang="ts" setup>
import { findGpxFilesQuery } from '@/slg-api/@pinia/colada/filesystem.gen';
import { inspectPgxFileQuery } from '@/slg-api/@pinia/colada/tracks.gen';
import { useQuery } from '@pinia/colada';

const selectedGpxFile = ref(null)

const { state: gpxFiles } = useQuery({...findGpxFilesQuery()})

const gpxInfoEnabled = computed(() => {
    return selectedGpxFile.value !== null
});


const { state: gpxData } = useQuery({
    ...inspectPgxFileQuery({
        path: {
            gpx_file: selectedGpxFile.value ?? ''
        }
    }),
    enabled: gpxInfoEnabled
})

</script>

In the example I want gpxData to be update if selectedGpxFile has a value. With this code the key and the options used by useQuery never changes.
A call is made after the first selection because of the enabled properties.
It's probably a problem caused by non reactive object passed as option.
To mitigate the problem I used defineQueryOptions

const gpxInpectQuery = defineQueryOptions((gpx_file: string|null) => {

    const options: Options<InspectPgxFileData> = {
        path: {
            gpx_file: gpx_file ?? ''
        }
    }

    return {
        key: inspectPgxFileQueryKey(options),
        query: async (context) => {
            if (gpx_file === null) {
                return null
            }
            const { data } = await Tracks.inspectPgxFile({
                ...options,
                ...context,
                throwOnError: true
            });
            return data;
        }
    };
})

const { state: gpxData } = useQuery(gpxInpectQuery, () => selectedGpxFile.value)

another solution whas to copy the useQueryOptions generated by the plughin and the key.

const gpxInfoEnabled = computed(() => {
    return selectedGpxFile.value !== null
});

const { state: gpxData } = useQuery({
/* this doesn't work, the generated key isn't reacteve
    key: inspectPgxFileQueryKey({
        path: {
            gpx_file: selectedGpxFile.value ?? ''
        }
    }),
*/
// this works correctly, the key can be a reactive property
    key: computed(() => (['tracks', 'inspect', selectedGpxFile.value])),
    query: async (context) => {
        const { data } = await Tracks.inspectPgxFile({
            path: {
                gpx_file: selectedGpxFile.value ?? ''
            },
            ...context,
            throwOnError: true
        });
        return data;
    },
    enabled: gpxInfoEnabled
})

Reproducible example or configuration

import { defineConfig } from "@hey-api/openapi-ts"

export default defineConfig({
  input: "http://localhost:8000/api/v1/openapi.json",
  output: "./src/slg-api",
  plugins: [
    '@hey-api/typescript',
    '@hey-api/client-axios',
    {
      name: "@hey-api/sdk",
      // NOTE: this doesn't allow tree-shaking
      asClass: true,
      operationId: true
    },
    {
      name: '@pinia/colada',
      groupByTag: true,
      queryOptions: true,
      queryKeys: {
        tags: true, 
      },
      mutationOptions: true,
    }
  ]
})

OpenAPI specification (optional)

Autogenerated by FastAPI

{
    "openapi": "3.1.0",
    "info": {
        "title": "Simple Local GAllery",
        "version": "0.1.0"
    },
    "paths": {
        "/api/v1/photos": {
            "get": {
                "tags": [
                    "photos"
                ],
                "summary": "Get Photos Summary",
                "operationId": "get_photos_summary",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "items": {
                                        "$ref": "#/components/schemas/PhotoSummary"
                                    },
                                    "type": "array",
                                    "title": "Response Get Photos Summary"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/settings/gallery-root": {
            "get": {
                "tags": [
                    "settings"
                ],
                "summary": "Get Gallery Root",
                "operationId": "get_gallery_root",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "string",
                                    "format": "path",
                                    "title": "Response Get Gallery Root"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/settings/gallery-root/reset": {
            "post": {
                "tags": [
                    "settings"
                ],
                "summary": "Reset Gallery Root",
                "operationId": "reset_gallery_root",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "string",
                                    "format": "path",
                                    "title": "Response Reset Gallery Root"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/tracks": {
            "get": {
                "tags": [
                    "tracks"
                ],
                "summary": "Get Tracks Summary",
                "operationId": "get_tracks_summary",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "items": {
                                        "$ref": "#/components/schemas/TrackSummary"
                                    },
                                    "type": "array",
                                    "title": "Response Get Tracks Summary"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/tracks/inspect/{gpx_file}": {
            "get": {
                "tags": [
                    "tracks"
                ],
                "summary": "Inspect Gpx File",
                "operationId": "inspect_pgx_file",
                "parameters": [
                    {
                        "name": "gpx_file",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Gpx File"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/Track"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/fs": {
            "get": {
                "tags": [
                    "filesystem"
                ],
                "summary": "Slg Filesystem Summary",
                "operationId": "get_filesystem_summary",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/FileSystemSummary"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/fs/photos/{path}": {
            "get": {
                "tags": [
                    "filesystem"
                ],
                "summary": "Find Files In Folder",
                "description": "Find photos in a specific folder",
                "operationId": "find_photos",
                "parameters": [
                    {
                        "name": "path",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "title": "Path"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "array",
                                    "items": {
                                        "type": "string",
                                        "format": "path"
                                    },
                                    "title": "Response Find Photos"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation Error",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/HTTPValidationError"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v1/fs/gpx": {
            "get": {
                "tags": [
                    "filesystem"
                ],
                "summary": "Find Gpx Files",
                "description": "Find GPX files in gallery root",
                "operationId": "find_gpx_files",
                "responses": {
                    "200": {
                        "description": "Successful Response",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "items": {
                                        "type": "string",
                                        "format": "path"
                                    },
                                    "type": "array",
                                    "title": "Response Find Gpx Files"
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "FileSystemSummary": {
                "properties": {
                    "folders": {
                        "items": {
                            "$ref": "#/components/schemas/FolderSummary"
                        },
                        "type": "array",
                        "title": "Folders"
                    },
                    "gpx_files_count": {
                        "type": "integer",
                        "title": "Gpx Files Count"
                    }
                },
                "type": "object",
                "required": [
                    "folders",
                    "gpx_files_count"
                ],
                "title": "FileSystemSummary"
            },
            "FolderSummary": {
                "properties": {
                    "folder": {
                        "type": "string",
                        "format": "path",
                        "title": "Folder"
                    },
                    "total_photos": {
                        "type": "integer",
                        "title": "Total Photos"
                    }
                },
                "type": "object",
                "required": [
                    "folder",
                    "total_photos"
                ],
                "title": "FolderSummary"
            },
            "HTTPValidationError": {
                "properties": {
                    "detail": {
                        "items": {
                            "$ref": "#/components/schemas/ValidationError"
                        },
                        "type": "array",
                        "title": "Detail"
                    }
                },
                "type": "object",
                "title": "HTTPValidationError"
            },
            "PhotoSummary": {
                "properties": {
                    "folder": {
                        "type": "string",
                        "title": "Folder"
                    },
                    "total_photos": {
                        "type": "integer",
                        "title": "Total Photos"
                    },
                    "first_taken_at": {
                        "type": "string",
                        "format": "date-time",
                        "title": "First Taken At"
                    },
                    "last_taken_at": {
                        "type": "string",
                        "format": "date-time",
                        "title": "Last Taken At"
                    }
                },
                "type": "object",
                "required": [
                    "folder",
                    "total_photos",
                    "first_taken_at",
                    "last_taken_at"
                ],
                "title": "PhotoSummary"
            },
            "Point": {
                "properties": {
                    "latitude": {
                        "type": "number",
                        "title": "Latitude"
                    },
                    "longitude": {
                        "type": "number",
                        "title": "Longitude"
                    },
                    "elevation": {
                        "anyOf": [
                            {
                                "type": "number"
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Elevation"
                    },
                    "timestamp": {
                        "type": "string",
                        "format": "date-time",
                        "title": "Timestamp"
                    }
                },
                "type": "object",
                "required": [
                    "latitude",
                    "longitude",
                    "timestamp"
                ],
                "title": "Point"
            },
            "Track": {
                "properties": {
                    "uid": {
                        "type": "string",
                        "title": "Uid"
                    },
                    "name": {
                        "type": "string",
                        "title": "Name"
                    },
                    "description": {
                        "anyOf": [
                            {
                                "type": "string"
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Description"
                    },
                    "timestamp": {
                        "anyOf": [
                            {
                                "type": "string",
                                "format": "date-time"
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Timestamp"
                    },
                    "points": {
                        "anyOf": [
                            {
                                "items": {
                                    "$ref": "#/components/schemas/Point"
                                },
                                "type": "array"
                            },
                            {
                                "type": "null"
                            }
                        ],
                        "title": "Points"
                    }
                },
                "type": "object",
                "required": [
                    "uid",
                    "name"
                ],
                "title": "Track"
            },
            "TrackSummary": {
                "properties": {
                    "uid": {
                        "type": "string",
                        "title": "Uid"
                    },
                    "name": {
                        "type": "string",
                        "title": "Name"
                    },
                    "total_points": {
                        "type": "integer",
                        "title": "Total Points"
                    },
                    "start_time": {
                        "type": "string",
                        "format": "date-time",
                        "title": "Start Time"
                    },
                    "finish_time": {
                        "type": "string",
                        "format": "date-time",
                        "title": "Finish Time"
                    }
                },
                "type": "object",
                "required": [
                    "uid",
                    "name",
                    "total_points",
                    "start_time",
                    "finish_time"
                ],
                "title": "TrackSummary"
            },
            "ValidationError": {
                "properties": {
                    "loc": {
                        "items": {
                            "anyOf": [
                                {
                                    "type": "string"
                                },
                                {
                                    "type": "integer"
                                }
                            ]
                        },
                        "type": "array",
                        "title": "Location"
                    },
                    "msg": {
                        "type": "string",
                        "title": "Message"
                    },
                    "type": {
                        "type": "string",
                        "title": "Error Type"
                    }
                },
                "type": "object",
                "required": [
                    "loc",
                    "msg",
                    "type"
                ],
                "title": "ValidationError"
            }
        }
    }
}

System information (optional)

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    bug 🔥Something isn't workingfeature 🚀New feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions