state
Overview
state
function is used to create a state slice.
state
provides a descriptor
which can be used to define one of the following:
- clientId
- typeDefs
- typePolicies
- possibleTypes
- onInit
- mutationUpdate
- effect
- optimisticResponse
- refetchQueries
- resolver
- action
Defining state
Defining a state slice is as simple as calling state
function.
export const themeState = state(descriptor => ...)
A state can also be defined as factory function that is executed in an injection context. It has access to inject()
via the EnvironmentInjector
from which they were configured.
export const themeState = () => {
const notificationService = inject(NotificationService);
return state(descriptor => ...);
}
A state
slice file name should be in the format <state-name>.state.ts
, this is a requirement as per our environment setup.
<state-name>
is singular by convention for simplicity.
Adding state
Once a state
slice is created it needs to be provided to the Angular DI system using one of the following methods:
Root injector
To add a state to the root injector, use the withStates
feature with provideApolloOrbit
.
For example themeState
can be provided as follows:
import { themeState } from '../states/theme/theme.state';
...
providers: [
provideApolloOrbit(
withApolloOptions(...),
withHttpLink(),
withStates(themeState)
)
]
Module injector
Typically, an Angular application is made up of multiple modules, each feature may have its own module and its own state logic.
States can be added to these child modules, using the provideStates
function.
import { provideStates } from '@apollo-orbit/angular';
import { authorState } from './states/author.state';
import { bookState } from './states/book.state';
...
@NgModule({
providers: [
provideStates(authorState, bookState)
]
...
})
export class LibraryModule { }
Route injector
States can also be provided as part of a route's configuration:
import { Routes } from '@angular/router';
import { LibraryComponent } from './library.component.ts';
import { provideStates } from '@apollo-orbit/angular';
import { authorState } from './library/states/author.state';
import { bookState } from './library/states/book.state';
export const LIBRARY_ROUTES: Routes = [
{
path: '',
component: LibraryComponent,
providers: [
provideStates(authorState, bookState)
]
}
];
import { Routes } from '@angular/router';
export const LIBRARY_ROUTES: Routes = [
{
path: 'library',
loadChildren: () => import('./library/library.routes').then(m => m.LIBRARY_ROUTES)
}
];
Route provided states should only handle mutations and actions that are defined within the route's module/component or any of its children modules/components.
onInit
onInit
defines a callback that is invoked when the state is initialised.
export const themeState = state(descriptor => descriptor
.onInit(cache => cache.writeQuery(...))
);
onInit
callback accepts the cache instance associated with the state and can be used to initialise cache data for that state. More on this in local state guide.
onInit
callback is called only once when the state is initialised. This can occur at one of the following times:
- When the Apollo instance associated with the state is first injected into the application.
- When the lazy-loaded module that provides the state is loaded.
- When the route that provides the state is first activated.