0

I'm playing around fp-ts to understand how does it work and I have a question. Let's say having a model like this:

export interface Category {
  id: number;
  categories: Category[];
  ...more fields
}

So, it's a graph of categories which each one has another categories and products, and also products can have categories.

My current API has 3 methods:

https://myshop.com/api/categories/ -> This will return all the categories graph. https://myshop.com/api/categories/${categoryId} -> This will return the specific category and they children categories.

My goal is build the complete graph so I have to first make a call for the first API method, then, for each category and the children do the second call.

This is my current attempt (It is not even syntax valid but to show you the idea)

getAllCategories(): TE.TaskEither<Error, Category[]> {
 return pipe(
   this.getFromUrl<ApiModel.CategoriesType>(
     'https://myshop.com/api/categories/',
     ApiModel.Categories,
   ),
   TE.map((categories) =>
     categories.map((category) => this.getCategories(category)),
   ),
 );
}


getCategory(categoryId: CategoryId): TE.TaskEither<Error, Category> {
 return pipe(
   this.getFromUrl<ApiModel.CategoryType>(
     `https://myshop.com/api/categories/${categoryId}/`,
     ApiModel.Category,
   ),
 );
}

private getCategories(category: ApiModel.CategoryType) {
 return pipe(
   TE.Do,
   TE.bind('parentCategory', () => this.getCategory(category)),
   TE.bind('childCategories', () => this.getChilds(category)),
   TE.bind(
     'result',
     ({
       parentCategory,
       childCategories,
     }): TE.TaskEither<Error, Category[]> => ()=> [
       parentCategory,
       ...childCategories,
     ],
   ), //Here I would need to fold but not sure how.
 );
}

private getChilds(
 category: Category,
): ((category: Category) => TaskEither<Error, Category>)[] {
 return pipe(
   category.categories,
   A.map((childCategory) => () => this.getCategory(childCategory.id)),
 );
}

Does anyone have an idea for this problem?

Thanks

Roberto
  • 41
  • 3
  • 1
    I think some information is missing between the value returned by your server and the interface type. If `getCategory` actually returned a `Category` value then there should be no need to call `getChilds`. My guess is that you are actually getting back an array of ids and not `Category` children. So the types should be updated to reflect that. It's a bit unclear exactly how you want to glue together the children and parents. I would recommend use `TE.chain` in `getAllCategories` and [sequenceArray](https://gcanti.github.io/fp-ts/modules/TaskEither.ts.html#sequencearray) for `getCategories` – Souperman Oct 07 '22 at 01:33

0 Answers0