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

Idea: flatten arrays of fragments when querying #421

Closed
nevir opened this issue Jul 19, 2016 · 13 comments
Closed

Idea: flatten arrays of fragments when querying #421

nevir opened this issue Jul 19, 2016 · 13 comments
Assignees

Comments

@nevir
Copy link
Contributor

nevir commented Jul 19, 2016

Because createFragment returns an array of fragments, you've got to be a bit careful when passing around its result - particularly when you're composing several fragments together:

const fragmentOne = createFragment(gql`
  fragment fragmentOne on Thing { 
      foo 
    }
`);
const fragmentTwo = createFragment(gql`
  fragment fragmentTwo on Thing { 
      ...fragmentOne
      bar
    }
`, fragmentOne); // It'd be nice to also support `[FragmentOne, ...]`
const fragmentThree = createFragment(gql`
  fragment fragmentThree on OtherThing { 
      foo
    }
`);

apollo.query(gql`{
  thing { 
    ...fragmentOne 
    other { 
      ...fragmentTwo
    }
  }
}`, [...fragmentOne, ...fragmentTwo]); // This expansion was surprising!

For this sort of situation, it'd be helpful if createFragment and query flattened out any nested arrays of FragmentDefinitions they got

@stubailo
Copy link
Contributor

I thought it already did this, or at least that was definitely the intention. Could you PR a failing test case for this? Then @Poincare should look at it.

@nevir
Copy link
Contributor Author

nevir commented Jul 19, 2016

Yup! Probably won't get around to that for a few days though

@stubailo
Copy link
Contributor

OK we will hopefully get to it before then.

@Poincare Poincare mentioned this issue Jul 19, 2016
4 tasks
@Poincare
Copy link
Contributor

Maybe I am misunderstanding the issue at hand but from the test added in #425, it seems that createFragment currently returns a flat array of FragmentDefinition instances. Could you check it out @nevir ?

@stubailo
Copy link
Contributor

@Poincare wait.. I just realized your test tests something totally different. Can you write a test where you pass an array of fragments into query?

@nevir
Copy link
Contributor Author

nevir commented Jul 20, 2016

Ah, yeah, sorry, the case is more like this:

it('should accepted nested arrays of fragment defs', () => {
  const fragmentDoc1 = gql`
    fragment authorDetails on Author {
      firstName
      lastName
      ...otherAuthorDetails
    }`;
  const fragmentDoc2 = gql`
    fragment otherAuthorDetails on Author {
      address
    }`;
  const fragmentDoc3 = gql`
    fragment evenMoreAuthorDetails on Auth {
      rating
    }`;
  const fragments2 = createFragment(fragmentDoc2);
  const fragments3 = createFragment(fragmentDoc3);
  const fragments1 = createFragment(fragmentDoc1, [fragments2, fragments3]);
  assert.equal(fragments2.length, 1);
  assert.equal(fragments3.length, 1);
  assert.equal(fragments1.length, 3);
});

@Poincare
Copy link
Contributor

Poincare commented Jul 20, 2016

So, I was assuming that the way you would declare a dependency between fragmentDoc2 and fragmentDoc3 is by calling createFragment on fragmentDoc1 and then passing along the result of that when we call createFragment on fragmentDoc2 (as in the unit test I wrote), i.e. createFragment should be used in order to manage the relationship between fragments rather than manually creating a nested array of fragments. If that's the intended use-case, I don't think createFragment would have to go out of its way to flatten anything.

I guess if we want to make it so that app developers can just group together fragments by creating nested arrays, I can add array flattening to createFragment (but, we will have to use the any type in TypeScript; a type for an arbitrarily nested array does not seem to work). Thoughts, @stubailo and @nevir?

@stubailo
Copy link
Contributor

@Poincare I think you should be able to create a fragment that has a dependency on multiple other fragments - how would you do that without this nested array approach?

I would definitely expect @nevir's approach to work.

Also, can't we just add one more level of possible nesting? I don't think it has to be arbitrary, just one more level.

@Poincare
Copy link
Contributor

Poincare commented Jul 20, 2016

@stubailo

So, we could do dependencies on other fragments by doing this:

fragments = createFragment(fragmentDoc1);
fragments = createFragment(fragmentDoc2, fragments)
fragments = createFragment(fragmentDoc3, fragments)

This declares a dependency between fragmentDoc1, fragmentDoc2, fragmentDoc3. @nevir's approach could work as well and I think doubly nested arrays should work as long as no one tries to use something like [fragment1, [fragment2, fragment3]] to create a dependency structure.

I think the key distinction is that the approach without any nesting, it is clear createFragment returns a list of fragments you pass around. With nesting, we make it seem as if createFragment is returning a single fragment which you can then put together with other fragments.

I'm fine with both approaches. We should probably do whichever is easier to use at the view layer level.

@stubailo
Copy link
Contributor

@Poincare I'd really like to do the nested array approach - that seems the most natural to me, rather than having to call createFragment multiple times.

@Poincare
Copy link
Contributor

Poincare commented Jul 20, 2016

See #437 for fix. Thanks for catching this @nevir!

@nevir
Copy link
Contributor Author

nevir commented Jul 21, 2016

Sweet, thanks for the quick turnaround!

@dminkovsky
Copy link
Contributor

Is this still implemented somehow in v3? Not finding this functionality anywhere, including the babel transforms etc.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Feb 15, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants