timhall / svelte-apollo

Svelte integration for Apollo GraphQL
MIT License
944 stars 68 forks source link

[question] how to capture query response into a variable? #96

Open beebase opened 3 years ago

beebase commented 3 years ago

In the example code you can use {#if ..} to wait for the query result. However, this obviously only works in the html part.

I've tried async/await to capture the result in to a variable but that doesn't work. Any suggestions?

<script>
  import { query } from "svelte-apollo";
  import { GET_BOOKS } from "./queries";
  const books = query(GET_BOOKS);
 // how to capture into a variable ??
 const list = books.data.books 
</script>
narutaro commented 3 years ago

query returns stores object. So try this way.

const books = async () => {
  const books = await query(GET_BOOKS);
  books.subscribe(data => console.log(data));
};
beebase commented 3 years ago

@narutaro Thanks for your suggestion. However "books" still remains a promise. Basically I want to make things synchronous.

const books = async () => {
  const books = await query(GET_BOOKS);
  books.subscribe(data => console.log(data));
};

// do something with the result
console.log("books|", books)     // prints out:  books| [... , ... , ...]
ZerdoX-x commented 2 years ago

I usually do like this:

<script>
  import { query } from "svelte-apollo";
  import { GET_BOOKS } from "./queries";
  const queryBooks = query(GET_BOOKS);
  $: books = $queryBooks.data?.books 
</script>
ikudosi commented 1 year ago

I usually do like this:

<script>
  import { query } from "svelte-apollo";
  import { GET_BOOKS } from "./queries";
  const queryBooks = query(GET_BOOKS);
  $: books = $queryBooks.data?.books 
</script>

How would you be able to update the books variable with this? I get a Cannot assign to read only property '{property}' of object '#<Object>'.

This is when I do something like a bind:value={books.name} with the example above.

ikudosi commented 1 year ago

@ZerdoX-x Never mind - answered my own question but ty for pointing the right direction. Not sure if this is the only way but it's not lucrative but works:

  let pageData

  (async () => {
    let queryData = await query(gql`
      query ($id: Int!) {
        shippingMethodMapping(id: $id) {
          shopify_code
          sap_code
          sap_carrier_type
        }
      }
    `, {
      variables: {
        id: $page.props.ship_mapping_id
      }
    })
    queryData.subscribe(data => {
      if (data.data) {
        pageData = Object.assign({}, data.data.shippingMethodMapping)
      }
    })
  })()
ZerdoX-x commented 1 year ago

How would you be able to update the books variable with this? I get a Cannot assign to read only property '{property}' of object '#<Object>'.

You can't update this variable because this is the cache from graphql. Response from your server stored in cache as source of truth

ikudosi commented 1 year ago

How would you be able to update the books variable with this? I get a Cannot assign to read only property '{property}' of object '#<Object>'.

You can't update this variable because this is the cache from graphql. Response from your server stored in cache as source of truth

Was able to change it by taking your approach with the .subscribe() and doing an pageData = Object.assign({}, data.data.shippingMethodMapping). The Object.asign will essentially copy the data to a new writable object.

ZerdoX-x commented 1 year ago

Was able to change it by taking your approach with the .subscribe() and doing an pageData = Object.assign({}, data.data.shippingMethodMapping). The Object.asign will essentially copy the data to a new writable object.

Then why not

<script>
  import { query } from "svelte-apollo";
  import { QUERY_SOME_DATA } from "./queries";
  const querySomeData = query(QUERY_SOME_DATA);
  $: someData = Object.assign({ }, $querySomeData.data?.shippingMethodMapping);
</script>

?

ikudosi commented 1 year ago

Was able to change it by taking your approach with the .subscribe() and doing an pageData = Object.assign({}, data.data.shippingMethodMapping). The Object.asign will essentially copy the data to a new writable object.

Then why not

<script>
  import { query } from "svelte-apollo";
  import { QUERY_SOME_DATA } from "./queries";
  const querySomeData = query(QUERY_SOME_DATA);
  $: someData = Object.assign({ }, $querySomeData.data?.shippingMethodMapping);
</script>

?

While it does render the value to the input, it somehow doesn't allow you to even type in the field. No console errors are being generated as well ¯_( ツ )_/¯.