Coder Social home page Coder Social logo

Comments (9)

nekitk avatar nekitk commented on August 29, 2024 7

found a way to insert an array of fragments into query by combining them into a single gql-tag:

gql`
    query {
        ...fragment1
        ...fragment2
    }
    
    ${fragments.reduce((acc, fragment) => gql`
        ${acc}
        ${fragment}
    `, '')}
`

from graphql-tag.

jnwng avatar jnwng commented on August 29, 2024 1

i think there is some use case for being able to pass both an array of fragments or map whose values are fragments (as those are often how our components are storing references to the fragments), but there hasn't been so much pain in just being explicit about what fragments are being interpolated. closing this for now.

from graphql-tag.

stubailo avatar stubailo commented on August 29, 2024

How are you creating the array of fragments? Perhaps there is a way to do it via interpolation.

from graphql-tag.

jesenko avatar jesenko commented on August 29, 2024

It is just an array of fragments generated by gql tagged string, e.g.

arrayOfFragments = [gql`frag1...`, gql`frag2...`]

In my use case, array is generated dynamically on js load time, based on registered child's component fragments, e.g.

const registeredComponents = [Component1, Component2, ...];
const arrayOfFragments = registeredComponents.map(c => c.fragments.someFragment)

Explicitly enumerating over array in gql is a possible workaround, however not the most elegant...

query SomeQuery {
  field {
     someRuntimeGeneratedFieldsOnFragments
  }
}
${arrayOfFragments[0]}
${arrayOfFragments[1]}
...

from graphql-tag.

helfer avatar helfer commented on August 29, 2024

Should we add in special support for this? I'm not sure if it's a common enough thing to make it worth it.

from graphql-tag.

jesenko avatar jesenko commented on August 29, 2024

For now, I just wrapped gql into custom gql tag literal, that expands arrays prior to passing it to gql, i.e.

import origGql from 'graphql-tag';

export default function(literals, ...args) {
  const newLiterals = [literals[0]];
  const newArgs = [];
  args.forEach((arg, i) => {
    if (Array.isArray(arg)) {
      newArgs.push(...arg);
      if (arg.length > 0) {
        const filler = Array(arg.length - 1).fill('');
        newLiterals.push(...filler);
        newLiterals.push(literals[i + 1]);
      }
    } else {
      newLiterals.push(literals[i + 1]);
      newArgs.push(arg);
    }
  });
  return origGql(newLiterals, ...newArgs);
}

This works just fine for my use case, so if this functionality is considered too specific to be included in graphql-tag, issue can be closed as far as I am concerned...

from graphql-tag.

KwanJunWen avatar KwanJunWen commented on August 29, 2024

Figured out another hacky way of doing this :
Helper function to combine multiple fragments body string into single string.

// pivotFragments combine fragments template string into a single string.
const pivotFragments = (fragments) => {
  if (Array.isArray(fragments) && fragments.length > 0) {
    return fragments.reduce((result, fragment, idx) => {
      let output = result;
      const { loc: { source: { body } } } = fragment;
      if (idx === 0) {
        output = body;
        return output;
      }
      return `${output}${body}`;
    }, '');
  }
  return '';
};

Then in your GraphQL schema :

const generateSchema = (fragments) => {
  const fs = pivotFragments(fragments);
  return gql`
    query MyQuery {
      user {...BarFields}
      income {...FooFields}
    }
    ${fs}
  `;
};

const schema = generateSchema([
  gql`
    fragment FooFields on Foo {
      id
      field
    }
  `,
  gql`
    fragment BarFields on Bar {
      id
      field
    }
  `,

...
// will be parsed as following
return gql`
    query MyQuery {
      user {...BarFields}
      income {...FooFields}
    }
    fragment FooFields on Foo {
      id
      field
    }
    fragment BarFields on Bar {
      id
      field
    }
  `;
])

Basically you extract the fragment string literal and insert them back to your gql tag and let the parser do the rest

from graphql-tag.

joshuaprior avatar joshuaprior commented on August 29, 2024

Or just call the tagged template function directly like this.

function gqlArray(fragmentArray) {
  const str = new Array(fragmentArray.length + 1).fill('');
  str.raw = str;
  return gql(str, ...fragmentArray);
}

// Usage
const fragments = [gql`...`, gql`...`];
const query = gql`
  query {
    ...
    ${gqlArray(fragments)}
  }
`;

from graphql-tag.

YuriiShchyrba avatar YuriiShchyrba commented on August 29, 2024

@nekitk just curious, I am trying to do something similar to what you wrote
const queryAndFragments = gql${query} ${fragments};
but for some reason when I am starting project webpack giving me this error: "error GraphQLError: Syntax Error: Unexpected ", does your code give you something like that ?

from graphql-tag.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.