Angular 5 - Creating a dynamic function that generates a different dynamic function

One of my latest projects involved creating a versatile function that generates switch-case statements dynamically.

export function generateReducer(initialState, reducerName: ReducerName, adapter: EntityAdapter<any>): (state, initialState) => IState {
  reducerName.plural = reducerName.plural ? reducerName.plural : reducerName.singular + 's';

  return function (state = initialState, action: any): IState {
    switch (action.type) {

        case `[${reducerName.plural} Section] Load Statistics ${reducerName.singular}`:
        case `[${reducerName.plural} Section] Load Details ${reducerName.singular}`:
        case `[${reducerName.plural} Section] Load ${reducerName.plural}`:
            {
                return { ...state, loading: true, loaded: false };
            }
            ...
}

and implementing it like this

export const adapter: EntityAdapter = createEntityAdapter();

export const initialState: State = adapter.getInitialState({
    loaded: false,
    loading: false,
    selectedId: null
});

export const reducer = generateReducer(initialState, { singular: 'Skill' }, adapter);

While everything works smoothly when testing the project with ng-serve (excluding AOT mode), encountering an error occurs when attempting to build for production using ng build --prod:

ERROR in src\app\skills\skills.module.ts(46,45): Error during template compile of 'SkillsModule' Function calls are not supported in decorators but 'generateReducer' was called in 'reducers' 'reducers' references 'reducers' 'reducers' references 'reducer' at src\app\skills\store\reducers\index.ts(18,13) 'reducer' calls 'generateReducer' at src\app\skills\store\reducers\skills.reducer.ts(26,24).

I've explored various solutions to resolve this issue but it seems like I need to provide some form of indication to the compiler to recognize it as a compile-time function that produces code. Any suggestions on how to tackle this kind of challenge?

UPDATE:

I have included a stackblitz repository to showcase the error,

https://stackblitz.com/edit/reducer-factory-ngrx

Feel free to download the application, update the package.json devDependencies "@angular/cli": "^1.6.0", and test running 'ng build --prod'

Answer №1

Make sure to include the following code in your "reducer.ts":

  export const reducer = generateReducer(initialState, { singular: 'Skill' }, adapter);

import { ActionReducerMap } from '@ngrx/store';
import { InjectionToken } from '@angular/core';

 // register reducer token
 export const reducerToken = new InjectionToken<ActionReducerMap<State>>(
   'Registered Reducers'
 );
 Object.assign(reducerToken, reducer);

 export function getReducers() {
   return reducer;
 }

Additionally, add this code in your app.module.ts file:

import { reducerToken, getReducers } from './reducer';


@NgModule({
imports: [
    BrowserModule,
    FormsModule,
    StoreModule.forRoot(reducerToken)
 ],
 declarations: [AppComponent, HelloComponent],
 providers: [
  {
    provide: reducerToken,
    useFactory: getReducers
  }
 ],
 bootstrap: [AppComponent]
})

I followed these steps and it worked perfectly for me. Hope this solution helps you as well!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Variations between <div/> and <div></div>

When using Ajax to load two divs, I discovered an interesting difference in the way they are written. If I write them like this: <div id="informCandidacyId"/> <div id="idDivFiles"/> Although both divs are being loaded, only one view is added ...

Resolving the Issue with onClick Events in Closures

Secrets of the JavaScript Ninja provides an interesting example: HTML <button id="test">Click me!</button> JavaScript var button = { clicked: false, click: function() { this.clicked = true; console.log("this:", this, ...

What steps should I take to create a consistently pristine and efficiently operating Angular 2 setup?

Currently mastering Angular 2 and making significant progress. However, encountering issues when attempting optimized builds with tree shaking. Constantly receiving error explosions deep within the Angular code. These errors may stem from bugs in Angular/n ...

Utilizing React for handling data exchange between child and parent components

I am still learning about React and material-ui, and I am exploring how to pass data from a child component to a parent component to update the parent state. Currently, when I try to update the state with a new date, it is being logged in the console but t ...

Exploring the Variance between 'npm run serve' and 'npm run dev' Commands in Vue.js Development

Can you explain to me the distinction between npm run serve and npm run dev in vuejs? Additionally, can you clarify why it is recommended to use the npm run serve command when running a project? ...

What is the best way to retrieve information in Next.js when there are changes made to the data, whether it be new

Could you share a solution for fetching data in Next.js when data is added, deleted, or edited? I tried using useEffect with state to trigger the function but it only works when data is added. It doesn't work for edit or delete operations. I have mult ...

Creating dynamic image carousels using the latest versions of Bootstrap and AngularJS

I have created an array that stores various images using angularJS: $scope.docImg = [ '../../Content/Image/BackGrounds/abra.png', '../../Content/Image/BackGrounds/background_black.jpg', '../../Content/I ...

Please input the number backwards into the designated text field

In my react-native application, I have a TextInput where I need to enter numbers in a specific order such as 0.00 => 0.01 => 0.12 => 1.23 => 12.34 => 123.45 and so on with each text change. I tried using CSS Direction "rtl" but it didn't work as expec ...

Having trouble with ReactJS updating the state in the correct format using moment?

In my ReactJS project, I am using a datepicker feature. However, I have encountered an issue where the state is not being updated with the selected date value after formatting it using moment.js. const [selectedDates, setSelectedDates] = useState([]) ...

What are the steps to incorporate an iframe containing uniquely designed XML content?

I'm currently working on a website project for a client who specifically wants to include news from the BBC. Despite spending 3 hours searching online, I haven't been able to successfully insert an XML file into an iframe and style it to the clie ...

What could be causing the malfunction of my token rotation feature in nextAuth?

I am developing a web application that involves working with an external API alongside my team member. We are making API requests using Next.js. I have implemented nextAuth for authentication, but I am facing issues with token rotation. After successful lo ...

The browser is sending numerous requests for the audio tag

I am facing an issue with an audio tag in my code. The URL is being parsed and returned by a function. <audio class="fr-draggable" controls autoplay [src]="extractAudioUrl(message)" style="width:100%"></audio> Unfortunately, the browser ends ...

Check if the user is null using React's useEffect hook and then perform a

I am currently working on implementing a protected route in Next JS. I have included a useEffect to redirect to the sign-in page if there is no user detected. const analytics = () => { const { userLoaded, user, signOut, session, userDetails, subscri ...

Utilizing jQuery to target a select element's two specific children

I am trying to target the parent element by matching two specific children elements. Here is my code: $('span:contains("11:00am"), span.name:contains("Tom")').parents("a").css("background-color","rgb(255, 255, 255)"); <script src="https://c ...

Is it secure to transmit Tenant ID's as GET parameters to the API in a Multi-Tenant database environment?

When working with a Multi-Tenant database, is it secure to pass Tenant ID's as query string parameters to the API while using popular JavaScript-based UI platforms like Angular or Vue and ensuring both the site and the API are HTTPS? For example, let ...

Trouble with the fetch request on the express root router when trying to connect with React

I am facing an issue while attempting to call the root router ('/') of Express using fetch API in React in production mode but it seems to be not working as expected. In my setup, I am utilizing a common server for serving static React views and ...

Utilizing Angular 5: Enhancing ngFor with a Pipe and a Click Event

Iterating through an array of objects using *ngFor, I apply various filters via pipes to manipulate the resulting list. One of these pipes relies on a user input from a search field. Upon clicking on one of the ngFor elements, the corresponding object is p ...

What is the value of x in the equation 2 raised to the power of x equals 800

Similar Question: What is the reverse of Math.pow in JavaScript? 2^x=i If i is given, how can we determine x using Javascript? ...

My customized mat-error seems to be malfunctioning. Does anyone have any insight as to why?

Encountering an issue where the mat-error is not functioning as intended. A custom component was created to manage errors, but it is not behaving correctly upon rendering. Here is the relevant page code: <mat-form-field appearance="outline"> < ...

Is it time to advance to the next input field when reaching the maxLength?

In my Vue form, I have designed a combined input field for entering a phone number for styling purposes. The issue I am facing is that the user needs to press the tab key to move to the next input field of the phone number. Is there a way to automaticall ...