Apollo-angular: Query/Mutation components

Created on 18 Mar 2019  路  4Comments  路  Source: kamilkisiela/apollo-angular

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;
      });
  }
}

feature

Most helpful comment

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.

All 4 comments

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.

If you want, feel free to implement it :)

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 ?

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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

simonhaenisch picture simonhaenisch  路  3Comments

qortex picture qortex  路  4Comments

bkinsey808 picture bkinsey808  路  3Comments

MaximS picture MaximS  路  7Comments

miquelferrerllompart picture miquelferrerllompart  路  7Comments