Effect CommunityEC
Effect Community2y ago
15 replies
lennerd

Convert Option to Effect and Best Practices

See the following example of a service. It has a findProject method returning an optional entity, meaning it can be undefined or null.

type Project = InferSelectModel<typeof projects>;

export default class ProjectRepository extends Context.Tag("ProjectRepository")<
  ProjectRepository,
  {
    findProject: (id: string) => Effect.Effect<Option.Option<Project>>;
  }
>() {}

export const ProjectRepositoryLive = Layer.effect(
  ProjectRepository,
  Effect.gen(function* () {
    const db = yield* Database;

    return {
      findProject(id) {
        return Effect.gen(function* () {
          const project = yield* Effect.promise(() =>
            db.query.projects.findFirst({ where: eq(projects.id, id) })
          );

          return Option.fromNullable(project);
        });
      },
    };
  })
);


Then I have the following program for receiving the entity (used inside a Remix loader).

const program = Effect.gen(function* () {
  const params = yield* LoaderParams;
  const { projectId } = yield* Schema.decodeUnknown(Params)(params);
  const repository = yield* ProjectRepository;
  const project = yield* repository.findProject(projectId);

  return json({ project });
});


How do I unwrap the Option type here? And what do you think about the composition and patterns. Any recommendations on how to improve it?

Thanks in advance! 🙂
Was this page helpful?