Skip to main content

Services

A service can access to:

State

You can access the local state by reading and writing on it

In this example the counter is decremented only if it is not 0

type State = { count: number };

export class CounterService extends Service<State> {
static initialState: State = { count: 0 };

async decrement() {
const value = this.state.count.get();
if (value === 0) {
return;
}
this.state.count.set(value - 1);
}
}

Access to the other services

For exemple we have a todoList form, it should append the form values to a todoList, then the form resets.

The submit method of TodoFormService calls the method append of TodoListService

type Form = { name: string };

type TodoFormState = Form;
export class TodoFormService extends Service<TodoFormState> {
static initialState: TodoFormState = { name: "" };

submit() {
const todoListService = this.services.get("todoList");
todoListService.append(this.state.get());

this.state.name.set("");
}
}

This way each service can have a single responsibility

init()

You can write an init method that will be executed right after the core is instantiated It is the perfect place to listen to some parts of the store that have been changed

export class MessageService extends Service {
init() {
this.dependencies.notifications.onReceive(this.onReceive);
}

onReceive(receivedNotification: string) {
this.store.messages.push(receivedNotification);
}
}

The dependencies

If your app is in clean architecture and uses the port-adapter pattern, you can access any of the dependencies in any service method

interface ShoesApiGateway {
get(): Promise<Shoe[]>;
}

type Dependencies = {
shoesApi: ShoesApiGateway;
};

export const Core = createCortexFactory<Dependencies>()(services);
type State = Shoe[];

export class CounterService extends Service<State> {
static initialState: State = [];

async loadShoes() {
const shoes = await this.dependencies.shoesApi.get();
this.state.set(shoes);
}
}

The dependencies can then be injected in the core

class RealShoesApiAdapter implements ShoesApiGateway {
async get() {
return axios.get<Shoe[]>("https://my-api/shoes/get");
}
}

const core = new Core({ shoesApi: RealShoesApiAdapter });