Socket
Socket
Sign inDemoInstall

ngrx-graphql

Package Overview
Dependencies
2
Maintainers
1
Versions
6
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    ngrx-graphql

Ease of NGRX and GraphQL


Version published
Weekly downloads
42
decreased by-17.65%
Maintainers
1
Install size
0.973 MB
Created
Weekly downloads
 

Changelog

Source

1.1.2 (2020-09-12)

Bug Fixes

  • latest ngrx-entity-relationship (697d4f5)

Readme

Source

ngrx-graphql

npm version CircleCI Coverage Status

A helper library for convertion of selectors made by ngrx-entity-relationship to a GraphQL query.

Supports

  • Angular 6 and ngrx/store@6
  • Angular 7 and ngrx/store@7
  • Angular 8 and ngrx/store@8
  • Angular 9 and ngrx/store@9
  • Angular 10 and ngrx/store@10

Installation

To install the package execute the next command npm install --save ngrx-graphql.

The next step is to add needed augments for types. It will help with integration of ngrx-graphql into ngrx-entity-relationship. For that add the next line in src/main.ts.

import 'ngrx-graphql/augments';

Usage

Note: you should be familiar with ngrx-entity-relationship.

Imagine we have a selector:

export const selectUser = rootEntity(
    selectUserState,
    relatedEntity(
        selectCompanyState,
        'companyId',
        'company',
        relatedEntity(
            selectAddressState,
            'addressId',
            'address',
        ),
    ),
);

And we want to get a GraphQL query like that:

{
    user(id: "1") {
        id
        firstName
        lastName
        companyId
        company {
            id
            name
            addressId
            address {
                id
                street
                city
                country
            }
        }
    }
}

The only issue is that the selector doesn't know fields of the entities. To solve this we need to define them manually as meta of every selector.

Don't forget to include fields for the id detection.

export const selectUser = rootEntity(
    selectUserState,
    {
        gqlFields: ['id', 'firstName', 'lastName'],
    },
    relatedEntity(
        selectCompanyState,
        'companyId',
        'company',
        {
            gqlFields: ['id', 'name'],
        },
        relatedEntity(
            selectAddressState,
            'addressId',
            'address',
            {
                gqlFields: ['id', 'street', 'city', 'country'],
            },
        ),
    ),
);

Profit, now we can use this selector to generate a GraphQL query via toGraphQL helper function.

const allUsers = toGraphQL('users', selectUser); // works for arrays of entities
const userId1 = toGraphQL('user(id: "1")', selectUser); // works with parameters
const userId2 = toGraphQL('user', {id: '2'}, selectUser); // converts parameters

The result will be

{
  users {
    id
    firstName
    lastName
    companyId
    company {
      id
      name
      addressId
      address {
        id
        street
        city
        country
      }
    }
  }
}
{
  user(id: "1") {
    id
    # and all other fields with relationships.
  }
}
{
  user(id: "2") {
    id
    # and all other fields with relationships.
  }
}

If we want we can combine them together to a single query

const combined = toGraphQL(
    toGraphQL('all:users', selectUser),
    toGraphQL('u1:user(id: "1")', selectUser),
    toGraphQL('u2:user', {id: '2'}, selectUser),
);

will generate

{
  all:users {
    id
    # ...
  }
  u1:user(id: "1") {
    id
    # ...
  }
  u2:user(id: "2") {
    id
    # ...
  }
}

Usage with HttpClient

An example of a ngrx effect and HttpClient.

@Injectable()
export class EntityEffects {
    @Effect()
    public readonly dataGraph$ = this.actions$.pipe(
        ofType(UserActionTypes.LOAD),
        switchMap(
            () => this.http.get<{data: {users: Array<User>}}>('http://localhost:3000/graphql', {
                params: {
                    // toGraphQL generates the query
                    query: toGraphQL('users', selectUser),
                }
            }).pipe(
                // reduces data, requires meta reducer from ngrx-entity-relationship.
                map(response => reduceGraph({
                    data: response.data.users,
                    selector: selectUser,
                })),
            ),
        ),
    );

    constructor(
        protected readonly actions$: Actions,
        protected readonly http: HttpClient,
    ) {
    }
}

Usage with Apollo Service

An example of a ngrx effect and Apollo service.

@Injectable()
export class EntityEffects {
    @Effect()
    public readonly dataGraph$ = this.actions$.pipe(
        ofType(UserActionTypes.LOAD),
        switchMap(
            () => this.apollo.query<{users: Array<User>}>({
                // toGraphQL generates the query
                query: gql(toGraphQL('users', selectUser)),
            }).pipe(
                // reduces data, requires meta reducer from ngrx-entity-relationship.
                map(response => reduceGraph({
                    data: response.data.users,
                    selector: selectUser,
                })),
            ),
        ),
    );

    constructor(
        protected readonly actions$: Actions,
        protected readonly apollo: Apollo,
    ) {
    }
}

Subscriptions

Usage of toGraphQL isn't enough to generate a subscription query. Here toSubscription solves the issue.

For example

const query = toSubscription(toGraphQL('users', action.selector));

will generate

subscription {
  users {
    id
    # ...
  }
}

With Apollo service it can be used like thath

apollo.subscribe({
  query: gql(toSubscription(toGraphQL('users', action.selector))),
}).subscribe(update => {
  // magic is here.
});

Mutations

Usage of toGraphQL isn't enough to generate a mutation query. Here toMutation solves the issue.

For example

const query = toMutation(toGraphQL('updateUser', {
  id: 'id1',
  data: {
    firstName: 'updatedFirstName',
    lastName: 'lastFirstName',
  }
}, action.selector));

will generate

mutation {
  updateUser(
    id:"id1",
    data: {
      firstName:"updatedFirstName",
      lastName:"lastFirstName"
    }
  ) {
    id
    # and all other fields with relationships.
  }
}

With Apollo service it can be used like that

apollo.mutate({
  mutation: gql(toMutation(toGraphQL('updateUser', {
    id: 'id1',
    data: {
      firstName: 'updatedFirstName',
      lastName: 'lastFirstName',
    }
  }, action.selector))),
}).subscribe(update => {
  // magic is here.
});

Query

Usage of toGraphQL isn't enough to generate a query with variables. Here toQuery solves the issue, but about that in the Variables section.

Variables

All toQuery, toSubscription and toMutation support variables. They can be passed as the first parameter. toGraphQL supports $ to define variables instead of values.

apollo.mutate({
  // the same for toQuery and toSubscription too.
  mutation: gql(toMutation({
    // definition of variables and their types.
    data: 'UpdateUserInput!',
  }, toGraphQL('updateUser', {
    id: 'id1', // a normal parameter with its value.
    // under $ parameters and their variables can be defined.
    $: {
      data: '$data',
    },
  }, action.selector))),
  variables: {
    data: {
      firstName: 'updatedFirstName',
      lastName: 'lastFirstName',
    },
  },
}).subscribe(update => {
  // magic is here.
});

will generate

mutation($data: UpdateUserInput!) {
  updateUser(
    id:"id1",
    data: $data
  ) {
    id
    # and all other fields with relationships.
  }
}

Keywords

FAQs

Last updated on 12 Sep 2020

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc