Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy inline queries #398

Closed
fehnomenal opened this issue Jul 10, 2022 · 8 comments · Fixed by #449
Closed

Lazy inline queries #398

fehnomenal opened this issue Jul 10, 2022 · 8 comments · Fixed by #449
Labels
Enhancement A new feature or improvement to Houdini's public API

Comments

@fehnomenal
Copy link
Contributor

fehnomenal commented Jul 10, 2022

With the store api lazy queries are now easily possible by defining them in a separate file. But I would love to be able to define them inline.

My idea to implement this is:
We can probably detect whether the query call is part of a variable declaration or standalone, right? I.e. we can differentiate between

const { data, refetch } = query(...);

and

query(...);

If this is the case we could abort the preprocessor logic early to not execute the query in load or on mount.

My thinking is that in the second case the user clearly does not intend to use the query data right now. So it seems logical to defer execution.

What do you think, @aivazis @jycouet?

@AlecAivazis
Copy link
Collaborator

Yea, i agree that we probably want to be able to do this. I wonder if it would be enough to support having a floating graphql tag which would result in a store that you could import as you wanted. Something like

<script>
    import FooStore from '$houdini/stores/Foo'

    graphql`
        query Foo { 
            bar
        }
    `

    // ....
</script>

Thoughts?

@AlecAivazis
Copy link
Collaborator

AlecAivazis commented Jul 10, 2022

Another option is that we could kind of merge these a bit so that a reference to an inline query returns the store:

<script>
    const FooStore = graphql`
        query Foo { 
            bar
        }
    `
</script>

@fehnomenal
Copy link
Contributor Author

I like both approaches, the second one even a bit more. This way there you can immediately see the floating graphql tag has a purpose 😅

@AlecAivazis AlecAivazis added the Enhancement A new feature or improvement to Houdini's public API label Jul 10, 2022
@jycouet
Copy link
Contributor

jycouet commented Jul 17, 2022

Actually, this 👇

<script>
    import { graphql } from "$houdini";
    
    graphql`
        query Foo { 
            bar
        }
    `
</script>

Is already generating the store GQL_Foo 🎉

But the preprocessor tries to do something with it (and it doesn't work).
If you add query(graphql...., everything will work as usual, but then you can't do mazy stuff.

I see 2 ways:
1/ When nothing infront of graphql => Disable preprocessor
2/ Having a function to say: Disable preprocessor. Something like store(graphql... (to ask only for the store creation, nothing more)

Bonus, the cool thing with GQL_Foo is that it's typed without putting the type manually.

@AlecAivazis
Copy link
Collaborator

AlecAivazis commented Jul 18, 2022

i'm personally not a fan of the floating graphql tag. i think saying const foo = graphql is much more clear instead of having to define a query and then import the store in 2 different lines. One benefit this has is that it's relatively straight forward to support. the preprocessor should just always turn a graphql tag into a reference to the appropriate store and then the inline functions can just look up the information they need from the store reference instead of having an object that contains the store

@jycouet
Copy link
Contributor

jycouet commented Jul 18, 2022

I see it as a great opportunity to mix styles (like #407).
If you don't like to define operations in an external document but you want to interact with stores directly 👍

It's almost like a bug today that it's not already working like:

  • graphql is creating the store
  • query(...) doing the preprocessor for query, having SSR & Browser
  • paginatedQuery(...) doing the preprocessor for paginatedQuery, having SSR & Browser & pagination

I have to say that the syntax with the import is also strange because you import something that you define inside the component. 😅
Strange, but enabling this:

<script context="module">
    import { GQL_Foo } from "$houdini";
    
    export async load(event) {
        await GQL_Foo.fetch({ event })
        return {}
    }
</script>
<script>
    import { graphql } from "$houdini";
    
    graphql`
        query Foo { 
            bar
        }
    `
</script>

We don't have to forget that the original question was about lazy.
So, maybe the clean & enabling things way is:

<script>
    import { graphql, store } from "$houdini";
    
    const myStoreNameFoo = store(graphql`
        query Foo { 
            bar
        }
    `)
    
    function randomAction() {
      myStoreNameFoo.fetch()
    }
</script>

With store(... giving you GQL_Foo

@AlecAivazis
Copy link
Collaborator

AlecAivazis commented Jul 18, 2022

hm maybe i'm missing something but i'm not sure what store gets you in that example. What i have in mind would look something like

<script context="module" lang="ts">
   // type is inferred from overloaded definitions of graphql
   const store = graphql`
        query MyQuery { 
        
        }
    `
    
    export async load(event) {
        await store.fetch({ event })
        return {}
    }
</script>
<script>
    $: browser && store.fetch()
</script>

{$store.value}

@AlecAivazis
Copy link
Collaborator

Just a heads up, support for this will be added as part of the upcoming work to support the new KitQL api 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Enhancement A new feature or improvement to Houdini's public API
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants