Ngrx-Entity not using defined DataService on Angular's standalone approach

61 Views Asked by At

I am currently trying to setup an Angular v17 Repository that uses Ngrx-Store with Ngrx-Entity and Ngrx-Data. I am using the standalone approach. For this, I was following things that were stated in Github Ngrx Issue #3934.

The problem is that a registered DataService is not being called as it should be.

I have an EntityService for the User-Entity that looks like this:

@Injectable()
export class UserEntityService extends EntityCollectionServiceBase<User> {
  constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
    super(USER_ENTITY_KEY, serviceElementsFactory);
  }
}

And I have a Mock-Environment where I want to use a custom UserDataMock to get user mocks from a custom JSON file. However, for simplicity I am currently generally injecting and registering this service without a check for the current environment.

@Injectable()
export class UserDataMockService extends DefaultDataService<User> {
  constructor(http: HttpClient, httpUrlGenerator: HttpUrlGenerator) {
    super(USER_ENTITY_KEY, http, httpUrlGenerator);
  }

  override getAll(): Observable<User[]> {
    console.log('UserDataMockService#getAll called');
    return of([
      {
        id: 1,
        firstName: 'Max',
        lastName: 'Mustermann',
      },
      {
        id: 2,
        firstName: 'Lisa',
        lastName: 'Webb',
      },
    ]);
  }
}

I register these two as providers of my AppComponent:

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [AsyncPipe, JsonPipe],
  template: `
    <h1>ngrx-data not using mock service</h1>
    <p>
      {{ allUsers$ | async | json }}
    </p> 

  `,
})
export class App {
  allUsers$: Observable<User[]>;

  constructor(userEntityService: UserEntityService) {
    this.allUsers$ = userEntityService.getAll();
  }
}

bootstrapApplication(App, {
  providers: [
    provideStore(),
    provideEntityData(entityConfig, withEffects()),
    provideEffects(),
    provideHttpClient(),

    UserEntityService,
    UserDataMockService,

    {
      provide: ENVIRONMENT_INITIALIZER,
      useValue() {
        const entityDataService = inject(EntityDataService);
        entityDataService.registerService(
          USER_ENTITY_KEY,
          inject(UserDataMockService)
        );
      },
      multi: true,
    },
  ],
}).catch(console.error);

... and this is my entityConfig:

const entityMetadata: EntityMetadataMap = {
  [USER_ENTITY_KEY]: {},
};

const pluralNames = {};

export const entityConfig: EntityDataModuleConfig = {
  entityMetadata,
  pluralNames,
};

Now when running the App, userDataMockService.getAll should be called and thus log to the console. But this is not the case. But it somehow recognizes, that there is another dataService for the user-entity, since removing the UserDataMockService from the providers (also then not registering) results in an error thrown at runtime, because, of course, there is no backend in place and the http-call was not successful.

In my AppComponent I tried to replace this.allUsers$ = userEntityService.getAll(); with this.allUsers$ = userEntityService.entities$;, but without any effect(1).

I created a Stackblitz that reproduces this behavior.

Any help is appreciated!


(1) which is pretty clear since the very first call of both should result in the same actions (http-call that then pushes the result into the store) as far as I know

0

There are 0 best solutions below