Angular - Decorators
Reference
State
Defines a state. Loona requires the State
decorator to be used on top of a class. It accepts defaults
which is an object that represents the default state and Loona writes that data to the cache on bootstrap. The second options is called typeDefs
, you define the GraphQL Schema in it. Both are optional.
import {State} from '@loona/angular';
@State({
defaults: {
books: [],
},
typeDefs: `
type Book {
id: ID!
title: String!
}
`,
})
class BooksState {}
Mutation
Defines a resolver of a mutation. The Mutation
requires one argument:
string
that represents the name of the mutation
import {Mutation} from '@loona/angular';
@State({...})
class BooksState {
@Mutation('addBook')
addBook(args, context) {
// ...
}
}
- a mutation document wrapped with
gql
function
import {Mutation} from '@loona/angular';
import gql from 'graphql-tag';
const addBook = gql`
mutation AddBook {
addBook($title: String!)
}
`
@State({...})
class BooksState {
@Mutation(addBook)
addBook(args, context) {
//
}
}
- a class with
mutation
as a static property
import {Mutation} from '@loona/angular';
import gql from 'graphql-tag';
class AddBook {
static mutation = gql`
mutation AddBook {
addBook($title: String!)
}
`;
}
@State({...})
class BooksState {
@Mutation(AddBook)
addBook(args, context) {
//
}
}
The Mutation
decorator should live on top of a method. We call that method resolver. It accepts two parameters, first on is an object with arguments that has been passed in mutation and the context.
Resolve
Defines a resolver of a field and requires one argument, a string
that is a path to the field you want to resolve. Should live on top of a method.
Resolvers look and work like regular GraphQL resolvers. They accept a parent, arguments, and a context.
import {Resolve} from '@loona/angular';
@State({...})
class BooksState {
@Resolve('Query.collection')
collection(parent, args, context) {
// ...
}
}
Update
Defines a an update function that runs whenever a mutation resolves. It's purpose is to update the cache (and queries) on every call and have it separated from the mutation. The update function has two arguments, first one contains an object with the information about the mutation and the second one contains the context.
import {Update} from '@loona/angular';
@State({...})
class BooksState {
@Update(AddBook)
updateBooks(info, context) {
context.patchQuery(gql`
{
books
}
`, data => {
data.books.push(info.result)
});
}
}
Effect
Defines an action handler that runs every time action happens. It's purpose is to handle the action and dispatch a new one. It has 2 arguments, second one contains the context, it includes dispatch
method. The first argument depends on a type of an action. If an action is a mutation then it has an interface of MutationObject
, otherwise it's a regular ActionObject
.
import {Effect} from '@loona/angular';
@State({...})
class BooksState {
@Effect(AddBook)
updateBooks(action, { dispatch }) {
// we receive a mutation here so let's check the status first
if (action.ok) {
dispatch({
type: 'BookAdded Success'
});
} else {
dispatch({
type: 'BookAdded Failure'
});
}
}
}