Code Monkey home page Code Monkey logo

satantime / ngrx-entity-relationship Goto Github PK

View Code? Open in Web Editor NEW
43.0 43.0 7.0 70.4 MB

ORM selectors for redux, @ngrx/store, @ngrx/entity and @ngrx/data. Ease of relationships with entities.

Home Page: https://ngrx-entity-relationship.sudo.eu

License: Other

JavaScript 2.70% TypeScript 93.62% HTML 3.45% CSS 0.05% Dockerfile 0.05% Shell 0.13%
angular entity foreign-keys graphql mutation ngrx ngrx-data ngrx-entity normalization orm query react reactjs redux related relations relationships subscription

ngrx-entity-relationship's Introduction

Hi there ๐Ÿ‘‹

My name is Michael,
and I am passionate about architecture for web applications, their development and cloud deployment.

Long story short: no pain, no gain, the harder, the better.

Please, don't hesitate to contact me:


If you wanted to help, please upvote:

Thank you in advance!


History of contributions:

ngrx-entity-relationship's People

Contributors

dependabot[bot] avatar renovate-bot avatar renovate[bot] avatar satantime avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

ngrx-entity-relationship's Issues

local cache from GraphQL based on object type as a root key

A possible solution is to use ApolloLink:

        // gqlHandleResponse is our handler from the library

        const addDateLink = new ApolloLink((operation, forward) =>
          forward(operation).map(gqlHandleResponse),
        );

        // eslint-disable-next-line unicorn/prefer-spread
        const link = addDateLink.concat(
          httpLink.create({
            uri,
          }),
        );

        return {
          cache: new InMemoryCache(),
          link,
        };

[FEATURE] suggestions for gqlFelds

Issue

No typing for gqlFields

export const USER = 'user';

export interface UserEntity {
  id: string;
  firstName: string;
  lastName: string;
}

export interface State extends EntityState<UserEntity> {
  selectedId?: string;
  loaded?: boolean;
  error?: string;
}

export interface PartialState {
  readonly [USER]: State;
}

export const getFeature = createFeatureSelector<PartialState, State>(USER);

export const selectRootUser = rootEntitySelector(getFeature);

export const getUser = selectRootUser({ gqlFields: [''] }); // !Missing suggestions for gqlFields!

Possible sulotion

Provide an ENTITY

declare global {
    export interface SELECTOR_META<ENTITY = any> {
        flatKey?: string;
        gqlFields?: Array<keyof ENTITY>;
    }
}

adjust rootEntitySelector.ts by providing the ENTITY to SELECTOR_META => SELECTOR_META<ENTITY>.

This is how it might look after compilation:

import { FEATURE_SELECTOR, HANDLER_RELATED_ENTITY, HANDLER_ROOT_ENTITY, ID_TYPES, TRANSFORMER } from './types';
export declare function rootEntitySelector<STORE, ENTITY, TRANSFORMED>(featureSelector: FEATURE_SELECTOR<STORE, ENTITY>, transformer: TRANSFORMER<ENTITY, TRANSFORMED>, meta: SELECTOR_META<ENTITY>): (metaOrRelationship?: SELECTOR_META<ENTITY> | HANDLER_RELATED_ENTITY<STORE, ENTITY>, ...relationships: Array<HANDLER_RELATED_ENTITY<STORE, ENTITY>>) => HANDLER_ROOT_ENTITY<STORE, ENTITY, TRANSFORMED, ID_TYPES>;
export declare function rootEntitySelector<STORE, ENTITY, TRANSFORMED>(featureSelector: FEATURE_SELECTOR<STORE, ENTITY>, transformer: TRANSFORMER<ENTITY, TRANSFORMED>): (metaOrRelationship?: SELECTOR_META<ENTITY> | HANDLER_RELATED_ENTITY<STORE, ENTITY>, ...relationships: Array<HANDLER_RELATED_ENTITY<STORE, ENTITY>>) => HANDLER_ROOT_ENTITY<STORE, ENTITY, TRANSFORMED, ID_TYPES>;
export declare function rootEntitySelector<STORE, ENTITY>(featureSelector: FEATURE_SELECTOR<STORE, ENTITY>, meta: SELECTOR_META<ENTITY>): (metaOrRelationship?: SELECTOR_META<ENTITY> | HANDLER_RELATED_ENTITY<STORE, ENTITY>, ...relationships: Array<HANDLER_RELATED_ENTITY<STORE, ENTITY>>) => HANDLER_ROOT_ENTITY<STORE, ENTITY, ENTITY, ID_TYPES>;
export declare function rootEntitySelector<STORE, ENTITY>(featureSelector: FEATURE_SELECTOR<STORE, ENTITY>): (metaOrRelationship?: SELECTOR_META<ENTITY> | HANDLER_RELATED_ENTITY<STORE, ENTITY>, ...relationships: Array<HANDLER_RELATED_ENTITY<STORE, ENTITY>>) => HANDLER_ROOT_ENTITY<STORE, ENTITY, ENTITY, ID_TYPES>;

Profit and a happy developer:

image

We don't need to guess the entity props any more.

Use all entity props without providing'em all in gqlFields: ['id', '...']

Is it possible to make the gqlFields little more dynamic? For example explicit with gqlFields: 'all' or implicit if gqlFields is not provided, all the entity props are used to generate a graphql query/mutation/subscription.

The only question is, how to handle nested props like:

interface User {
  id: string;
  firstName: string;
  profile: Settings;
}

interface Settings {
  theme: 'light' | 'dark';
  permissions: Permission[];
  // ...
}

interface Permission {
  id: string;
  name: string;
  value: boolean;

Maybe it'd be even cooler with this approach like in prisma

export const getUser = selectRootUser({
  gqlFields: { id: true, firstName: true, profile: { permissions: { value: true } },
});

would generate following graphql query

{
  user {
    id
    firstName
    profile {
      permissions {
        value
      }
    }
  }
}

Support of parentId

Add a support to group child entities based on a parent id field.

const e1 = {id: 1};
const e2 = {id: 2, parentId: 1};
const e3 = {id: 3, parentId: 1};

to get

const e = {
  id: 1,
  children: [
    {id:2, parentId: 1},
    {id:3, parentId: 1},
  ],
};

then we can make people happy

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

File: e2e/angular10-ivy-false/package.json
Error type: Nested package.json must not contain renovate configuration. Please use packageRules with paths in your main config instead.

reduceGraph doesn't update collection in store

On page loading first I dispatch loadMyFiles, this effect executes and populates the store with original data.
When I unlink a file, I dispatch unlinkMyFileSuccess, the effect executes, it sends a request to the backend and received data but doesn't update the store with new data.
The new array of files is pretty similar to the original one, with the only difference in one file record - one or two fields disappear from one record. Not replaced with an undefined, affected object in an array of files is missing this property.

public readonly loadMyFiles$ = createEffect(() =>
    this.actions$.pipe(
      ofType(loadMyFiles, uploadFileSuccess, unlinkMyFileSuccess),
      switchMap(({ cid }) =>
        cidTask(
          cid,
          this.myLibraryFileService.getUploadedFiles().pipe(
            mergeMap((myLibraryFiles: Array<MyLibraryFile>) => [
              cidPayload({
                cid,
                payload: myLibraryFiles.map((myLibraryFile) => myLibraryFile.id),
              }),
              reduceGraph({
                data: myLibraryFiles,
                selector: cpSelectMyFiles,
              }),
            ]),
          ),
        ),
      ),
    ),
  );

many to many?

Hello,
I have tried your library and it works perfectly.
https://ngrx-entity-relationship.herokuapp.com/user/main

I was looking for a solution for my project, it was not easy to find this library.

I did not understand if the library manages relations:

  • many to many
  • one to many

how do i associate the staff attribute?

export interface Company {
    id: string;
    name: string;

    staff?: Array<User>; <===== ?????????

    admin?: User;
    adminId?: string;

    address?: Address;
    addressId?: string;
}

ngrxEntityRelationshipReducer with @ngrx/data has unexpected behavior

Problem

The ngrxEntityRelationshipReducer meta reducer does not work as expected when used along with @ngrx/data.

Here is a stackblitz project to illustrate the behavior:
stackblitz

For these examples say the backend returns that:

{
  "id": "1",
  "firstName": "John",
  "lastName": "Smith",
  "companyId": "1",
  "company": {
    "id": "1",
    "name": "Magic",
    "adminId": "2",
    "addressId": "1",
    "address": {
      "id": "1",
      "street": "Main st.",
      "city": "Town",
      "country": "Land"
    }
  }
}

ngrxEntityRelationshipReducer does update the other entity collections, but since @ngrx/data has already added the response from the server to the entity cache, the entity in the cache still contains the related entities that were in the server response.

So if we dispatch reduceGraph after @ngrx/data loads this user, the entities in entityCache will look like that:

User

{
  "id": "1",
  "firstName": "John",
  "lastName": "Smith",
  "companyId": "1",
  "company": {
    "id": "1",
    "name": "Magic",
    "adminId": "2",
    "addressId": "1",
    "address": {
      "id": "1",
      "street": "Main st.",
      "city": "Town",
      "country": "Land"
    }
  }
}

Company

{
  "id": "1",
  "name": "Magic",
  "adminId": "2",
  "addressId": "1"
}

Address

{
  "id": "1",
  "street": "Main st.",
  "city": "Town",
  "country": "Land"
}

Worth Mentioning

Something to note, @ngrx/data does not automatically initialize the entityCache with empty collections. It starts like that:

{
  entityCache: { }
}

So if we tell @ngrx/data to load a user entity then dispatch reduceGraph on the response, the store will look something like that:

{
  entityCache: {
    User: { ... }
  }
}

The simplest way I found to deal with this is to just add empty arrays into all the entity collections when the app initializes. You can also see this in the stackblitz example.

Select filtered relations

Here is my case. I have two stores: orders and articles. Order is connected with articles with one to many relation.
artciles contain orderId which is the relational key .
Here is the structure of both objects:

export interface IOrders {
  id: string;
  tableName: string;
  operator: string;
  createdAt: Date;
  elements: IArticles[];
  ...
}

export interface IArticles {
  id: string;
  orderId: string;
  quantity: number;
  article: string;
  description: string;
  status: ArticleStatus
  ...
}

So, what I have into the selectors:
First I need to fetch all articleIds which have a specific status

const allArticleIds = createSelector(selectArticleState, state => Object.values(state.entities)
  .filter(article => [ArticleStatus.ORDERED, ArticleStatus.RETURNED, ArticleStatus.LOCKED, ArticleStatus.CANCELED].includes(article.status))
  .map(article => article.id));

then lets try to create a selector which will return only desired articles:

...
export const selectArticleState = createFeatureSelector<fromArticles.State>('articles');
...
const selectAllOrderedArticles = createSelector(
  s => s,
  // selecting ids
  allOrderedArticleIds,
  selectArticleState,
);

If I create a store selector from the last:

public readonly articles$ = this.store.select(selectAllOrderedArticles);

and subscribe to that, as result will have only the filtered articles. This is great, but now I want to select orders, with their ONLY FILTERED articles! How I can do that?

What I've trying is following:

export const selectOrderState = createFeatureSelector<fromOrders.State>('orders');
...

const selectOrderWithArticles = rootEntity(
  selectOrderState,
  childrenEntities(
    selectAllOrderedArticles,
    'orderId',
    'elements',
  ),
);

const selectOrdersWithArticles = rootEntities(selectOrderWithArticles);

const allOrdersIds = createSelector(selectOrderState, state => state.ids);

const selectAllOrders = createSelector(
  // selecting the whole store
  s => s,
  // selecting ids
  allOrdersIds,
  // selecting all users with desired relationships
  selectOrdersWithArticles,
);

I expected selectOrderWithArticles to return orders with the filtered articles because I've used selectAllOrderedArticles, but actually I receive all articles instead.

Do I have something wrong, or there is a bug in the package?

Accept an id selector as a param of a relationship selector.

The goal is to avoid switchMap from the next logic:

store.select(selectCurrentUserId).pipe( // selecting the id of a current user
    switchMap(id => store.select(selectUserWithCompany, id)),  // selecting the user with desired relationships
).subscribe(user => {
     // profit
});

The desired code should look like:

store.select(selectUserWithCompany, selectCurrentUserId).subscribe(user => {
     // profit
});

Handling missing entry in related entity state

Let's say I have a Book entity like

interface Book {
 authorId: string;
 author: Author;
 // ...
}

I can use relatedEntitySelector and combine it with rootEntity to get a selector that returns books where the authorId field has been automatically looked up in my Author state to hydrate the author field.

Now let's say that' I have too many authors to load them all upfront. The authorId will most likely not find an entity matching authorId. It would be great to have a way to detect these misses.

I think that what currently happens in the callback defined in relatedEntity is that simply ignore the issue:

        // Line ~120 in relatedEntity.ts
        const valueEntities = [];
        for (const id of ids) {
            if (!featureState.entities[id]) {
                continue; // Ignore related ids that don't appear in the matching feature state
            }

            // ...

            entityValue = {...featureState.entities[id]} as RELATED_ENTITY;

            // ...

            valueEntities.push(entityValue);
        }

Is there any suggestion or best practice to do that? If I haven't missed any build-in functionality, I guess my options are:

  • Put all of this logic further down the line once the selectors have returned my entities. Unfortunately at that point I need to define my relationships again, I can't just build upon what I've defined with relatedEntitySelector.
  • Re-define relatedEntity and before the above continue statement, do something interesting (most likely call a user-defined function).

Thank you.

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Warning

These dependencies are deprecated:

Datasource Name Replacement PR?
npm @angular/http Unavailable
npm @types/redux Unavailable
npm codecov Unavailable
npm protractor Unavailable
npm tslint Unavailable
npm tslint-microsoft-contrib Unavailable

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

circleci
.circleci/config.yml
  • win 4.1.1
  • satantime/puppeteer-node 14.21.3
  • satantime/puppeteer-node 8.17.0
  • satantime/puppeteer-node 8.17.0
  • satantime/puppeteer-node 8.17.0
  • satantime/puppeteer-node 8.17.0
  • satantime/puppeteer-node 10.24.1
  • satantime/puppeteer-node 10.24.1
  • satantime/puppeteer-node 12.22.12
  • satantime/puppeteer-node 12.22.12
  • satantime/puppeteer-node 12.22.12
  • satantime/puppeteer-node 12.22.12
  • satantime/puppeteer-node 12.22.12
  • satantime/puppeteer-node 12.22.12
  • satantime/puppeteer-node 12.22.12
  • satantime/puppeteer-node 12.22.12
  • satantime/puppeteer-node 12.22.12
  • satantime/puppeteer-node 12.22.12
  • satantime/puppeteer-node 12.22.12
  • satantime/puppeteer-node 12.22.12
  • satantime/puppeteer-node 12.22.12
  • satantime/puppeteer-node 14.21.3
  • satantime/puppeteer-node 14.21.3
docker-compose
docker-compose.yml
dockerfile
Dockerfile
  • satantime/puppeteer-node 16.20.1-buster-slim
npm
docs/package.json
  • @docusaurus/core 2.0.0-beta.15
  • @docusaurus/plugin-content-docs 2.0.0-beta.15
  • @docusaurus/plugin-google-gtag 2.0.0-beta.15
  • @docusaurus/plugin-sitemap 2.0.0-beta.15
  • @docusaurus/remark-plugin-npm2yarn 2.0.0-beta.15
  • @docusaurus/theme-classic 2.0.0-beta.15
  • @mdx-js/react 1.6.22
  • clsx 2.0.0
  • react 18.2.0
  • react-dom 18.2.0
  • react-toggle 4.1.3
e2e/a10/package.json
  • @angular/animations 10.2.5
  • @angular/common 10.2.5
  • @angular/compiler 10.2.5
  • @angular/core 10.2.5
  • @angular/forms 10.2.5
  • @angular/platform-browser 10.2.5
  • @angular/platform-browser-dynamic 10.2.5
  • @angular/router 10.2.5
  • @ngrx/data 10.1.2
  • @ngrx/effects 10.1.2
  • @ngrx/entity 10.1.2
  • @ngrx/store 10.1.2
  • rxjs 6.5.5
  • tslib 2.6.0
  • zone.js 0.10.3
  • @angular-devkit/build-angular 0.1002.4
  • @angular/cli 10.2.4
  • @angular/compiler-cli 10.2.5
  • @types/jasmine 3.5.14
  • @types/jasminewd2 2.0.10
  • @types/node 12.20.55
  • jasmine-core 3.5.0
  • jasmine-spec-reporter 5.0.2
  • karma 5.2.3
  • karma-chrome-launcher 3.1.1
  • karma-jasmine 3.3.1
  • karma-jasmine-html-reporter 1.5.4
  • protractor 7.0.0
  • puppeteer 10.4.0
  • ts-node 8.10.2
  • typescript 3.9.10
  • ngrx-entity-relationship *
  • npm 6.14.18
e2e/a11/package.json
  • @angular/animations 11.2.14
  • @angular/common 11.2.14
  • @angular/compiler 11.2.14
  • @angular/core 11.2.14
  • @angular/forms 11.2.14
  • @angular/platform-browser 11.2.14
  • @angular/platform-browser-dynamic 11.2.14
  • @angular/router 11.2.14
  • @ngrx/data 11.1.1
  • @ngrx/effects 11.1.1
  • @ngrx/entity 11.1.1
  • @ngrx/store 11.1.1
  • rxjs 6.6.3
  • tslib 2.6.0
  • zone.js 0.10.3
  • @angular-devkit/build-angular 0.1102.19
  • @angular/cli 11.2.19
  • @angular/compiler-cli 11.2.14
  • @types/jasmine 3.6.11
  • @types/jasminewd2 2.0.10
  • @types/node 12.20.55
  • jasmine-core 3.6.0
  • jasmine-spec-reporter 5.0.2
  • karma 5.2.3
  • karma-chrome-launcher 3.1.1
  • karma-jasmine 4.0.2
  • karma-jasmine-html-reporter 1.5.4
  • protractor 7.0.0
  • puppeteer 10.4.0
  • ts-node 8.10.2
  • typescript 4.0.8
  • ngrx-entity-relationship *
  • npm 6.14.18
e2e/a12/package.json
  • @angular/animations 12.2.17
  • @angular/common 12.2.17
  • @angular/compiler 12.2.17
  • @angular/core 12.2.17
  • @angular/forms 12.2.17
  • @angular/platform-browser 12.2.17
  • @angular/platform-browser-dynamic 12.2.17
  • @angular/router 12.2.17
  • @ngrx/data 12.5.1
  • @ngrx/effects 12.5.1
  • @ngrx/entity 12.5.1
  • @ngrx/store 12.5.1
  • rxjs 6.6.7
  • tslib 2.6.0
  • zone.js 0.11.8
  • @angular-devkit/build-angular 12.2.18
  • @angular/cli 12.2.18
  • @angular/compiler-cli 12.2.17
  • @types/jasmine 3.7.8
  • @types/jasminewd2 2.0.10
  • @types/node 12.20.55
  • jasmine-core 3.7.1
  • jasmine-spec-reporter 5.0.2
  • karma 6.3.20
  • karma-chrome-launcher 3.1.1
  • karma-jasmine 4.0.2
  • karma-jasmine-html-reporter 1.7.0
  • protractor 7.0.0
  • puppeteer 10.4.0
  • ts-node 10.9.1
  • typescript 4.2.4
  • ngrx-entity-relationship *
  • npm 6.14.18
e2e/a13/package.json
  • @angular/animations 13.4.0
  • @angular/common 13.4.0
  • @angular/compiler 13.4.0
  • @angular/core 13.4.0
  • @angular/forms 13.4.0
  • @angular/platform-browser 13.4.0
  • @angular/platform-browser-dynamic 13.4.0
  • @angular/router 13.4.0
  • @ngrx/data 13.2.0
  • @ngrx/effects 13.2.0
  • @ngrx/entity 13.2.0
  • @ngrx/store 13.2.0
  • rxjs 7.5.7
  • tslib 2.6.0
  • zone.js 0.11.8
  • @angular-devkit/build-angular 13.3.11
  • @angular/cli 13.3.11
  • @angular/compiler-cli 13.4.0
  • @types/jasmine 3.10.11
  • @types/jasminewd2 2.0.10
  • @types/node 12.20.55
  • jasmine-core 4.0.1
  • jasmine-spec-reporter 5.0.2
  • karma 6.3.20
  • karma-chrome-launcher 3.1.1
  • karma-jasmine 4.0.2
  • karma-jasmine-html-reporter 1.7.0
  • protractor 7.0.0
  • puppeteer 13.1.3
  • ts-node 10.9.1
  • typescript 4.5.5
  • ngrx-entity-relationship *
  • npm 6.14.18
e2e/a6/package.json
  • @angular/animations 6.1.10
  • @angular/common 6.1.10
  • @angular/compiler 6.1.10
  • @angular/core 6.1.10
  • @angular/forms 6.1.10
  • @angular/http 6.1.10
  • @angular/platform-browser 6.1.10
  • @angular/platform-browser-dynamic 6.1.10
  • @angular/router 6.1.10
  • @ngrx/effects 6.1.2
  • @ngrx/entity 6.1.2
  • @ngrx/store 6.1.2
  • core-js 2.6.12
  • rxjs 6.2.2
  • zone.js 0.8.29
  • @angular-devkit/build-angular 0.8.9
  • @angular/cli 6.2.9
  • @angular/compiler-cli 6.1.10
  • @angular/language-service 6.1.10
  • @types/jasmine 2.8.19
  • @types/jasminewd2 2.0.10
  • @types/node 8.9.5
  • jasmine-core 2.8.0
  • jasmine-spec-reporter 4.2.1
  • karma 5.0.8
  • karma-chrome-launcher 2.2.0
  • karma-jasmine 1.1.2
  • karma-jasmine-html-reporter 0.2.2
  • protractor 5.4.4
  • puppeteer 2.1.1
  • ts-node 7.0.1
  • typescript 2.9.2
  • ngrx-entity-relationship *
  • npm 6.14.18
e2e/a7/package.json
  • @angular/animations 7.2.16
  • @angular/common 7.2.16
  • @angular/compiler 7.2.16
  • @angular/core 7.2.16
  • @angular/forms 7.2.16
  • @angular/platform-browser 7.2.16
  • @angular/platform-browser-dynamic 7.2.16
  • @angular/router 7.2.16
  • @ngrx/effects 7.4.0
  • @ngrx/entity 7.4.0
  • @ngrx/store 7.4.0
  • core-js 2.6.12
  • rxjs 6.3.3
  • tslib 1.14.1
  • zone.js 0.8.29
  • @angular-devkit/build-angular 0.13.10
  • @angular/cli 7.3.10
  • @angular/compiler-cli 7.2.16
  • @angular/language-service 7.2.16
  • @types/jasmine 2.8.19
  • @types/jasminewd2 2.0.10
  • @types/node 8.10.66
  • jasmine-core 2.8.0
  • jasmine-spec-reporter 4.2.1
  • karma 5.0.7
  • karma-chrome-launcher 2.2.0
  • karma-jasmine 1.1.2
  • karma-jasmine-html-reporter 0.2.2
  • protractor 5.4.4
  • puppeteer 2.1.1
  • ts-node 7.0.1
  • typescript 3.2.4
  • ngrx-entity-relationship *
  • npm 6.14.18
e2e/a8/package.json
  • @angular/animations 8.2.14
  • @angular/common 8.2.14
  • @angular/compiler 8.2.14
  • @angular/core 8.2.14
  • @angular/forms 8.2.14
  • @angular/platform-browser 8.2.14
  • @angular/platform-browser-dynamic 8.2.14
  • @angular/router 8.2.14
  • @ngrx/data 8.6.1
  • @ngrx/effects 8.6.1
  • @ngrx/entity 8.6.1
  • @ngrx/store 8.6.1
  • rxjs 6.4.0
  • tslib 1.14.1
  • zone.js 0.9.1
  • @angular-devkit/build-angular 0.803.29
  • @angular/cli 8.3.29
  • @angular/compiler-cli 8.2.14
  • @angular/language-service 8.2.14
  • @types/jasmine 3.4.6
  • @types/jasminewd2 2.0.10
  • @types/node 8.10.66
  • jasmine-core 3.4.0
  • jasmine-spec-reporter 4.2.1
  • karma 4.4.1
  • karma-chrome-launcher 2.2.0
  • karma-jasmine 2.0.1
  • karma-jasmine-html-reporter 1.4.2
  • protractor 5.4.4
  • puppeteer 5.5.0
  • ts-node 7.0.1
  • typescript 3.5.3
  • ngrx-entity-relationship *
  • npm 6.14.18
e2e/a9/package.json
  • @angular/animations 9.1.13
  • @angular/common 9.1.13
  • @angular/compiler 9.1.13
  • @angular/core 9.1.13
  • @angular/forms 9.1.13
  • @angular/platform-browser 9.1.13
  • @angular/platform-browser-dynamic 9.1.13
  • @angular/router 9.1.13
  • @ngrx/data 9.2.1
  • @ngrx/effects 9.2.1
  • @ngrx/entity 9.2.1
  • @ngrx/store 9.2.1
  • rxjs 6.5.5
  • tslib 1.14.1
  • zone.js 0.10.3
  • @angular-devkit/build-angular 0.901.15
  • @angular/cli 9.1.15
  • @angular/compiler-cli 9.1.13
  • @angular/language-service 9.1.13
  • @types/jasmine 3.5.14
  • @types/jasminewd2 2.0.10
  • @types/node 12.20.55
  • jasmine-core 3.5.0
  • jasmine-spec-reporter 4.2.1
  • karma 4.4.1
  • karma-chrome-launcher 3.1.1
  • karma-jasmine 2.0.1
  • karma-jasmine-html-reporter 1.5.4
  • protractor 5.4.4
  • puppeteer 10.4.0
  • ts-node 8.10.2
  • typescript 3.7.7
  • ngrx-entity-relationship *
  • npm 6.14.18
e2e/r7/package.json
  • @reduxjs/toolkit 1.9.5
  • @testing-library/jest-dom 5.17.0
  • @testing-library/react 12.1.5
  • @testing-library/user-event 13.5.0
  • @types/jest 27.5.2
  • @types/node 14.18.53
  • @types/react 17.0.62
  • @types/react-dom 17.0.20
  • @types/react-redux 7.1.25
  • @types/redux 3.6.0
  • react 17.0.2
  • react-dom 17.0.2
  • react-redux 7.2.9
  • react-scripts 5.0.1
  • redux 4.2.1
  • typescript 4.9.5
  • web-vitals 2.1.4
  • ngrx-entity-relationship *
  • npm 6.14.18
libs/ngrx-entity-relationship/package.json
package.json
  • @angular-devkit/architect 0.1402.12
  • @angular-devkit/build-angular 12.2.18
  • @angular/animations 12.2.17
  • @angular/common 12.2.17
  • @angular/compiler 12.2.17
  • @angular/compiler-cli 12.2.17
  • @angular/core 12.2.17
  • @angular/forms 12.2.17
  • @angular/language-service 12.2.17
  • @angular/platform-browser 12.2.17
  • @angular/platform-browser-dynamic 12.2.17
  • @angular/router 12.2.17
  • @commitlint/cli 17.6.7
  • @commitlint/config-conventional 17.6.7
  • @nrwl/angular 12.10.1
  • @nrwl/cli 12.10.1
  • @nrwl/tao 12.10.1
  • @nrwl/workspace 12.10.1
  • @semantic-release/changelog 6.0.3
  • @semantic-release/exec 6.0.3
  • @semantic-release/git 10.0.1
  • @semantic-release/github 9.0.4
  • @types/jasmine 3.10.11
  • @types/node 14.18.53
  • codecov 3.8.3
  • codelyzer 6.0.2
  • coveralls 3.1.1
  • dotenv 16.3.1
  • eslint 8.45.0
  • husky 8.0.3
  • jasmine-core 4.6.0
  • jasmine-spec-reporter 7.0.0
  • karma 6.4.2
  • karma-chrome-launcher 3.2.0
  • karma-coverage 2.2.1
  • karma-ie-launcher 1.0.0
  • karma-jasmine 4.0.2
  • karma-jasmine-html-reporter 2.1.0
  • karma-junit-reporter 2.0.1
  • lint-staged 13.2.3
  • npm 6.14.18
  • ng-packagr 12.2.7
  • postcss 8.4.26
  • prettier 2.8.8
  • puppeteer 17.1.3
  • rxjs 7.8.1
  • semantic-release 19.0.5
  • ts-node 10.9.1
  • tslib 2.5.0
  • tslint 6.1.3
  • tslint-defocus 2.0.6
  • tslint-lines-between-class-members 1.3.6
  • tslint-microsoft-contrib 6.2.0
  • typescript 4.3.5
  • zone.js 0.13.0
  • npm 6.14.18
nvm
.nvmrc
  • node 14.21.3

  • Check this box to trigger a request for Renovate to run again on this repository

how to configure ngrxEntityRelationshipReducer

Hi,
first thank you for this awesome library, you really helped me out there when trying to implement entity relations with ngrx/data! I am currently integrating it into my app and stumbled upon how to add the ngrxEntityRelationshipReducer to the root import. So far I have

import { ngrxEntityRelationshipReducer } from 'ngrx-entity-relationship';

StoreModule.forRoot(reducers, {
      metaReducers: [
        ngrxEntityRelationshipReducer
      ],
      //...
    }),

but I get this error on startup:

ERROR in app/app.module.ts(99,9): Error during template compile of 'AppModule' Only initialized variables and constants can be referenced in decorators because the value of this variable is needed by the template compiler in 'ngrxEntityRelationshipReducer' 'ngrxEntityRelationshipReducer' references 'ngrxEntityRelationshipReducer' 'ngrxEntityRelationshipReducer' references 'ngrxEntityRelationshipReducer' 'ngrxEntityRelationshipReducer' is not initialized.

Unfortunately I couldn't find any examples in the Hero/Villain/Fight examples to check how you used it. Do you have any advice?

gqlIgnore

There may happen cases, when we don't shan't to send a shape as gql query. For example, it's Frontend only selection.

This rel should be marked as gqlIgnore flag and should be skipped during query building.

NGRX-Entity-Relationship Graph do not receive the selector

I am using ngrx-entity-relationship in my angular project with @ngrx/store.

When I try to use reduceGraph inside an effect, no change occurs in the store, and when I check the devtool I see that the selector is not reaching

this is the effect code

loadPostById$ = createEffect(() =>
    this.actions$.pipe(
      ofType(PostActions.loadPostById),
      concatMap(({ id }) =>
        this.postService.loadPostById(id).pipe(
          map((post) => reduceGraph({
            data: post,
            selector: rootPost()
          })),
          catchError((error) => of(PostActions.loadPostByIdFailure({ error })))
        )
      )
    )
  );

this is the relationships code


export const rootPost = rootEntitySelector(fromPosts.selectPostsState);
export const relPostUser = relatedEntitySelector(
  fromUsers.selectUsersState,
  'publisherId',
  'publisher'
)

This is what i see in devtool, it has no selector this is what i see in the devtool

image

Use root selector factories for rel factories

Along with usage of feature selectors would be great to support root selector factories too.

In such a case, the rel selector would simply extract feature selector, I'd selector and spread meta data (gql fields etc).

Looking to select a list of all entities from two entity caches using NgRx Data

Hi,

Awesome library! I am currently looking to use your library to select a list of all entities from two entity caches using NgRx Data.

Currently, I have something like:

export const selectUser = rootEntity(
this.entityCache.users, // the selector of the user's feature.

 // now we define a relationship between a user and a company.
relatedEntity(
selectCompanyState, // a selector of the company's feature.
'companyId', // the key in the user's model that points to the company's id.
'company', // the key in the user's model that should be fulfilled with the company's entity.
),
);

I want to be able to do something like the below which will select all users and associated company.

export const selectUsers = rootEntities(selectUser);

But it seems to be wanting an id or list of ids to filter by.

Is it possible with this library to return all?

Depreceted NGRX selectors with props

GitHub issue

In Angular 12 selectors with props are deprecated.

The suggested way of selecting the entities mentioned in quick steps would therefore be deprecated as well:

const selectUsers = rootEntities(selectUser);

// NGRX
this.store.select(this.selectUsers, ['1', '2']);

The suggested way of rewriting according to the github issue is to use factory selector like this:

export const users = (ids: number[]) => createSelector(this.selectUsers, (users) => {
    return ... code to select users by ids
});

// Then consume it as
this.store.select(users(['1', '2']));

Currently this is not possible because the rootEntity and rootEntities requires ids as an argument and it matches the following overload in NGRX so it is also flagged as deprecated:

/**
 * @deprecated Selectors with props are deprecated, for more info see {@link https://github.com/ngrx/platform/issues/2980 Github Issue}
 */
export declare function createSelector<State, Props, S1, Result>(s1: SelectorWithProps<State, Props, S1>, projector: (s1: S1, props: Props) => Result): MemoizedSelectorWithProps<State, Props, Result>;

The first argument is of type

export declare type SelectorWithProps<State, Props, Result> = (state: State, props: Props) => Result;

which matches (for rootEntities) your type HANDLER_ROOT_ENTITIES because it contains (state, id): Array

export type HANDLER_ROOT_ENTITIES<S, E, T, I> = ENTITY_SELECTOR<S, E> & {
    (state: S, id: undefined | null | Array<I> | STORE_SELECTOR<S, undefined | null | Array<I>>): Array<T>;
};

Would it be possible to rewrite the rootEntity and rootEntities functions and/or create new ones for filtering by ids so that something like the following would work?

/** Code in ngrx-entity-relationship */
export function findByIds(state, ids): {
   .. code to filter by IDs
   return entities;
} 

/** Code in user apps */
const selectAllUsers = rootEntities(selectUser);
const selectUsersById = (ids) => createSelector(selectAllUsers, (state) => findByIds(state, ids));

this.store.select(selectUsersById(['1', '2']));

The idea is to move the arguments into the functions itself to avoid selector with properties.

populate ids automatically on graphql reduce

if the id field hasn't been set, then we should detect its values based on the related entity and populate its value.

So

parentId: null,
parent: {
  id: 123,
},

would become in the store

parentId: 123,

the same for sets.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.