Despo
Despo

Reputation: 51

Should ngrx entities be stored at a feature level or at an app level?

I am trying to build an application using ngrx. As an exemple, let's say that this is a project management application (such as Jira). Requirements say that it should be built using ngrx.

In this application, I've identified the following features:

So my folder structure could look like this:

- board (feature module)
- core
- dashboard (feature module)
- issue (feature module)
- project (feature module)
- shared
- app.component.ts
- app-routing.module.ts
- app.module.ts

I also have a set of entities (stored using the entity module of ngrx). Those entities are kinda obvious: projects, issues, boards.

What I'm having trouble with is finding the best way to store the entities in my store, especially because they are shared between my different modules. For example:

Should those entities be stored at the feature module level or rather at the root store level?

If I store them at a feature level, it could look like this:

{
  "board": {
    "boardEntities": {
      "0" {
        "id": 0,
        "projectId": 1,
        "name": "My super board",
        "configuration": { ... }
      }
    }
  },
  "projects": {
    "projectEntities": {
      "1": {
        "id": 1,
        "name": "my project",
        "issueIds": [0, 1, 2, 3, 4], // all issues of this project
        "owner": "owner" 
      }
    }
  },
  "issues": {
    issueEntities: { 
      "0": {
        // ...
      }
    }
  }
}

But then the loading part is kinda awkward. For example when my dashboard tries to display the issues, they might not be in my state yet. I will dispatch an action like new fromDashboard.loadIssues(), and this action will be caught in an effect that will load the issues, but this effect is present in the issue feature. Because issues can be load from pretty much all features, my loadIssues effect (located in the issue feature folder) will have to listen to fromDashboard.loadIssues, fromProject.loadIssues and fromBoard.loadIssues.It looks weird because I don't feel like the Issue feature should be aware of dashboard/project/board.

Another way would be to store it at the root level, e.g:

{
  "entities": {
    "projectEntities": {
      // ...
    },
    "boardEntities": {
      // ...
    },
    "issueEntities": {
      // ...
    }
  },
  "board": {
    // ...
  },
  "projects": {
    // ...
  },
  "issues": {
    // ...
  }
}

Where entities actions and reducers will be located in the core module. The reducers and effects would still have to listen to multiple actions (e.g fromDashboard.loadIssues, fromProject.loadIssues and fromBoard.loadIssues), but to me here it is okay if the core is aware of all features (after all it is the core of the application).

But it somehow does not feel right, or at least to me it does not look like the standard ngrx way of doing it, but I might be wrong.

Thanks for any help.

Upvotes: 1

Views: 865

Answers (1)

timdeschryver
timdeschryver

Reputation: 15505

From what I read, the entities make up your whole application and are needed in every module. For this case, I think it would make perfect sense to add them at the root.

I wrote a little piece about this topic in Sharing data between modules is peanuts.

Upvotes: 0

Related Questions