Loona

Loona

  • React
  • Angular
  • GitHub
  • Blog

›Advanced

Introduction

  • What is Loona?
  • Getting Started

Essentials

  • State
  • Queries
  • Mutations
  • Updates
  • Actions
  • Effects

Advanced

  • Mutation as Action
  • Lazy Loading
  • Dependency Injection
  • Error Handling
  • Server Side Rendering
  • How Store works

Recipies

  • Testing
  • Plugins
  • Migrate from NGRX or Redux

API

  • Loona client
  • Decorators
  • Context
  • EffectContext
  • Other types and interfaces
Edit

Angular - Mutation as Action

It's not only an action that can be dispatched, you can do it too with a mutation. If you don't need the result of a mutatiin and you want to access data only through your queries, dispatching an action makes a lot of sense in this case.

How to define

Mutations are dispatched pretty much the same way as actions. You first need to define one:

export class AddBook {
  static mutation = gql`
    mutation AddNewBook($title: String!) {
      addBook(title: $title) @client {
        id
        title
      }
    }
  `;

  variables: {title: string};

  constructor(title: string) {
    this.variables = {
      title,
    };
  }
}

Okay, now we've got a class called AddBook that is a mutation and looks like an action but instead of type property is has mutation and variables.

How to dispatch

To dispatch the AddBook in a component you simple follow the same steps like with a regular action:

import {Loona} from '@loona/angular';

@Component({...})
export class NewBookComponent {
  constructor(private loona: Loona) {}

  addBook(title: string) {
    this.loona.dispatch(
      new AddBook(title)
    );
  }
}

Use with Effects

Since we used mutation as an action it means we can use Effects on it too

@State()
class BooksState {
  constructor(private notifications: NotifictionService) {}

  @Effect(AddBook)
  bookAdded(action, context) {
    this.notifications.notify('New book');
  }
}

Shape

When a mutation is dispatched Loona.mutate() is called under the hood. After mutation resolves Loona runs effects and the action object they get has a different structure then mutation itself.

Instead of receiving an object with mutation and variables properties it uses the same shape like other actions have. The type property says it's a mutation.

{
  type: 'mutation';
  options: MutationOptions;
  ok: boolean;
  // ...
}
  • type - always equals mutation.
  • options - the same object that Loona.mutate() accepts so it contains: mutation, variables and options like fetchPolicy and others.
  • ok - it's true if mutation was succesfull, or false otherwise

Status

Base on the ok property you can tell if the mutation resolved or errored.

Besides those three options Loona emits a different shape depending if mutation resolved or not.

If mutation was succesfull:

{
  type: 'mutation',
  options:  { mutation: ..., variables: ... },
  ok: true,
  data: ...
}

but on failure:

{
  type: 'mutation',
  options:  { mutation: ..., variables: ... },
  ok: false,
  error: ...
}

Now with all that knowledge we can make a different notification based on the status of an action:

@State()
class BooksState {
  constructor(private notifications: NotifictionService) {}

  @Effect(AddBook)
  bookAdded(action, context) {
    const title = action.options.variables.title;
    
    if (action.ok) {
      this.notifications.notify(`New the '${title}' added`);
    } else {
      this.notifications.notify(`Adding '${title}' failed`);
    }
  }
}

Use in resolvers

You define resolvers as you would normally do except instead of passing the name of the mutation you pass a class:

import {State, Mutation} from '@loona/angular';

@State({...})
export class BooksState {
  @Mutation(AddBook)
  addBook(args, context) {
    // some logic
  }

  @Update(AddBook)
  addToBooks(mutation, context) {
    // some logic
  }
}

It's the same with Updates, a class instead of a string.

← EffectsLazy Loading →
  • How to define
  • How to dispatch
  • Use with Effects
    • Shape
    • Status
  • Use in resolvers
LoonaCopyright © 2019 The Guild
Documentation
AngularReact
Community
Stack OverflowSpectrum ChatGitHub
Blog & Social
MediumTwitter
More
FAQContact & Support