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

Query/Mutation components #1132

Open
chihab opened this issue Mar 18, 2019 · 4 comments
Open

Query/Mutation components #1132

chihab opened this issue Mar 18, 2019 · 4 comments
Labels
feature New addition or enhancement to existing solutions
Milestone

Comments

@chihab
Copy link

chihab commented Mar 18, 2019

Wouldn't be interesting to have Query and Mutation components as the ones we have on react-apollo ?

  • Required input: query: a GraphQL query document parsed into an AST by graphql-tag
  • Outputs: data, loading and error events
  • Render prop: projected template with context containing data, loading and error values

Basic query component usage would be (with the render prop pattern) :

<ngx-query [query]="query">
	<ng-template let-data let-loading="loading" let-error="error">
		<div *ngIf="loading">
			Loading...
		</div>
		<div *ngIf="error">
			Error :(
		</div>
		<p>
			{{ data | json }}
		</p>
	</ng-template>
</ngx-query>

where the query in the component would be:

query = gql`query getMessage {
           message {
              text
          }
}`;

and a basic implementation of the Query component (Render Prop use case) would be:

import { TemplateRef, Input, ContentChild, OnInit, ViewContainerRef, Component, AfterViewInit } from '@angular/core';
import { Apollo } from 'apollo-angular';

@Component({
  selector: 'ngx-query',
  template: `<ng-container *ngTemplateOutlet="template, context: {
    $implicit: data,
    loading: loading,
    error: error
  }"></ng-container>`
})
export class QueryComponent implements OnInit {
  @Input() query; // Should be typed
  @ContentChild(TemplateRef) template: TemplateRef<any>;

  data: any;
  loading: boolean;
  error: any;

  constructor(private apollo: Apollo) {
  }

  ngOnInit() {
    this.apollo
      .watchQuery({
        query: this.query,
      })
      .valueChanges.subscribe(result => {
        this.data = result.data;
        this.loading = result.loading;
        this.error = result.error;
      });
  }
}
@kamilkisiela
Copy link
Owner

I wouldn't use it, that's why I decided to not implement it. Here's what I did back then: https://stackblitz.com/edit/apollo-angular-token-service-directive?file=app%2Flist.component.ts, instead of a component, it was a directive.

@kamilkisiela
Copy link
Owner

If you want, feel free to implement it :)

@chihab
Copy link
Author

chihab commented Mar 18, 2019

Could you elaborate on why you would not use it ? Would you use the query component in React ?
My understanding is like it is an anti-pattern to use it that way in Angular and injecting/using apollo service on the interested components would be a better implementation... while on React there would be no harm using it that way because "everything is a component" (even the router). Does it make sense ?

@kamilkisiela
Copy link
Owner

kamilkisiela commented Mar 18, 2019

About React, that's why I was trying it out, because I used it there. I personally, don't like Render Props pattern, it's just ugly and adds a noise to the component, in most cases the Higher Order Component pattern was my first choice.

About Angular, I tried it out and it felt odd. Since we're using HTML and an operation will be available in Component class I saw no point of messing up the template. Because everything is a stream, it was easier for me to use a service (generated by our codegen).

I think it would make more sense once Ivy lands, we get those mixins and hocs. I was consider to work on it a while ago but I will still wait to a stable version of Ivy.

@kamilkisiela kamilkisiela added this to the Ivy stuff milestone Apr 1, 2019
@kamilkisiela kamilkisiela added the feature New addition or enhancement to existing solutions label Apr 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature New addition or enhancement to existing solutions
Projects
None yet
Development

No branches or pull requests

2 participants