The selector in Angular ngrx 8 is failing to retrieve a value

I have experience with Angular but I am new to ngrx. I am attempting to retrieve values from my server and display them on the screen. I can see that the values are coming back from the server, and then the effect is triggered by the action:

https://i.sstatic.net/QGMjt.png

However, my simple component is not displaying anything:

ProfileComponent.ts:

export class ProfileComponent implements OnInit {
  network$= this.store.select(a=>a.NetworkInfo)
  profiles$: Observable<Profile[]> = this.store.select(state => state.Profiles);
  constructor(private store:Store<NetAlertState>) { }

  ngOnInit() {
    this.store.dispatch({ type: '[Profile Component] getAllProfiles' });
    this.store.dispatch({ type: '[Profile Component] getNetworkInfo' });    
  }

}

profile.component.html:

    <div *ngFor="let profile of profiles$ | async">
    {{ profile.name }}
    </div>

net-alert.actions.ts:

export const getAllProfiles = createAction('[Profile Component] getAllProfiles');
export const getNetworkInfo = createAction('[Profile Component] getNetworkInfo');
export const loadProfilesSuccess = createAction('[Profile Component] loadProfilesSuccess',props<{items:Profile[]}>());
export const loadNetworkInfoSuccess = createAction('[Profile Component] loadNetworkInfoSuccess', props<NetworkInfo>());
export const loadProfilesFailure = createAction('[Profile Component] loadProfilesFailure',props<String>());
export const loadNetworkInfoFailure = createAction('[Profile Component] loadNetworkInfoFailure',props<String>());

net-alert.reducer.ts

    export const initialState: NetAlertState = {
    Profiles:null,
    NetworkInfo:null,
    isLoading: false,
    error: null
}

export const NetAlertReducer = createReducer(
    initialState,
    on(NetAlertActions.getAllProfiles, state => ({ ...state,isLoading:true ,error:null})),
    on(NetAlertActions.loadProfilesSuccess, (state,profiles) => ({ Profiles:profiles,...state ,isLoading:false ,error:null})),
    on(NetAlertActions.loadProfilesFailure, (state,err) => ({ ...state,isLoading:false ,error:err})),
    on(NetAlertActions.getNetworkInfo, state => ({ ...state ,isLoading:true ,error:null})),
    on(NetAlertActions.loadNetworkInfoSuccess, (state,res) => ({ ...state,NetworkInfo:res,isLoading:false ,error:null})),
    on(NetAlertActions.loadNetworkInfoFailure, (state,err) => ({ ...state,isLoading:false ,error:err})),
  );



export function reducer(state: NetAlertState | undefined, action: Action) {
    return NetAlertReducer(state, action);
  }

net-alert.effects.ts:

@Injectable()
export class NetAlertEffects {

    loadProfiles$ = createEffect(() =>
     this.actions$.pipe(
        ofType('[Profile Component] getAllProfiles'),
        mergeMap(() => this.dataService.getAllProfiles()
          .pipe(
            map(res => ({ type: '[Profile Component] loadProfilesSuccess', payload: res })),
            catchError(() => of({ type: '[Profile Component] loadProfilesFailure' }))
          )
        )
      )
  );

  constructor(
    private actions$: Actions,
    private dataService: DataService
  ) {}
}

net-alert.state.ts:

  export interface NetAlertState {
     isLoading: boolean;
     error: any;
     NetworkInfo: NetworkInfo;
     Profiles: Profile[];
 }

 export interface Profile {
  Mac: string;
  NickName: string;
  CreateDate: Date;
  Sites?: any;
}

root-state.ts:

export interface AppStates {
  netAlert: NetAlertState;
}

export const netAlertReducers: ActionReducerMap<AppStates> = {
    netAlert: netAlertRerucers.reducer
 }; 

app.module.ts:

  @NgModule({
  declarations: [
    AppComponent,
    ProfileContainerComponent,
    ProfileComponent
  ],
  imports: [
    HttpClientModule,
    BrowserModule,
    AppRoutingModule,
    StoreModule.forRoot(netAlertReducers),
    EffectsModule.forRoot([NetAlertEffects]),
    StoreDevtoolsModule.instrument({
      maxAge: 25, // Retains last 25 states
      logOnly: environment.production, // Restrict extension to log-only mode
    }),
    RootStoreModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Can anyone point out where I may have made a mistake?

Thank you!

Answer №1

To ensure your code works effectively, it is crucial to have a reducer in place to handle state updates triggered by the loadProfilesSuccess action. Here's an example of how you can implement this:

const myReducer = createReducer(
  initialState, // representing NetAlertState
  on(from.loadProfilesSuccess, (state, action) => {
     // update state based on the action payload
  }),
)

export function reducer(state: NetAlertState, action: Action) {
    return myReducer(state, action);
}

Additionally, make sure to utilize your actions throughout your codebase for consistency and proper functionality:

ngOnInit() {
    this.store.dispatch(getAllProfiles());
    this.store.dispatch(getNetworkInfo());
}
loadProfiles$ = createEffect(() =>
     this.actions$.pipe(
        ofType(getAllProfiles),
        mergeMap(() => this.dataService.getAllProfiles()
          .pipe(
            map(res => loadProfilesSuccess(res)),
            catchError(() => of(loadProfilesFailure())
          )
        )
      )
    );

Answer №2

The "netAlert" state selector seems to be missing, which is crucial for building other selectors. It should look something like this:

selectors.ts

import * as fromNetAlertState from "./state";

export const netAlertState = (state: State) => state.netAlert;

export const selectProfiles = createSelector(
  netAlertState,
  (state: fromNetAlertState.State) => state.Profiles
);

component.ts

profiles$: Observable<Profile[]> 

ngOnInit() {
    this.profiles$ = this.store.pipe(select(selectProfiles))
}

Answer №3

To properly initialize your profiles, it is recommended to include them in the ngOnInit method as shown below:

export class ProfileComponent implements OnInit {
  network$: any;
  profiles$: Observable<Profile[]>
  
  constructor(private store:Store<NetAlertState>) { }

  ngOnInit() {
    this.store.dispatch({ type: '[Profile Component] getAllProfiles' });
    this.store.dispatch({ type: '[Profile Component] getNetworkInfo' });
    this.network$ =  this.store.select(a=>a.NetworkInfo);
    this.profiles$ = this.store.pipe(select(state => state.Profiles));
  }
}

Furthermore, it is advisable to leverage the pipe operator for better efficiency.

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

Retrieving a specific item using its ID from a JSON file with Ionic 5

Newcomer's query For multiple Ionic pages, I require fetching a specific item by ID from a centralized JSON file. The structure of my JSON data is as follows: { "items": [ { "id":"0", "link&q ...

Creating ngModel dynamically with *ngFor in Angular 2: A guide

I've been struggling with this for the past couple of days - how can I have a new ngModel for each iteration within an *ngFor loop? The idea is that I load a list of questions, and within each question there are 2 propositions. Here's the HTML: & ...

What is the best way to incorporate "thread.sleep" in an Angular 7 app within a non-async method like ngOnInit()?

Despite the numerous questions and solutions available on Stack Overflow, none of them seem to work when called from a component's init function that is not asynchronous. Here's an example: private delay(ms: number) { return new Promise( ...

Angular implementing a carousel feature using the ngFor directive

Currently, I am working on implementing a carousel feature. The images in the carousel are sourced from a string array and I want to be able to cycle through them when clicking on the left or right arrows. How can I achieve this functionality using only ...

Securing React: Best Practices for State Management

Consider the following scenario: const UserProfile: React.FC<RouteComponentProps> = (props) => { const { isAdmin} = useContext(GlobalContext); if (isAdmin()) { return <CriticalFeature/>; } else { return <NonCritic ...

ES6 Update: Manipulating Nested Arrays with JavaScript

I have the following list of items: [ { idItem: "1", name: "apple", itemLikes: [{ id: "1", idItem: "1" }] } ] My goal is to simply add a new object to the itemLikes array. Here is my ...

Is there a way for me to navigate from one child view to another by clicking on [routerLink]?

Currently, I am facing an issue with switching views on my Angular website. The problem arises when I attempt to navigate from one child view to another within the application. Clicking on a button with the routerlink successfully takes me to the new view, ...

Is it possible to send a JSON object to a RESTful API in Angular 2+ without relying on cookies?

Struggling to send a json type object to the rest service in an (angular2+ springMvc + java) web project. It's proving to be quite challenging, and on top of that, I'm unable to utilize cookies too. ...

Ensuring that all environmental variables are properly set in Typescript by utilizing interfaces and resolving union to tuple type discrepancies

In order to create a required application env variables file named env.d.ts, I want to ensure that any modifications or additions to it will trigger TypeScript errors and runtime errors for the checkEnv function if a value is not set. To achieve this, I h ...

Creating Separate User and Admin Navigation in Angular: Step-by-Step Guide

I am facing an issue in my Angular project where I want to segregate the admin and user navigation similar to that of an e-commerce website. However, the children route is not functioning properly for the dashboard or user sections. Whenever I click on the ...

Angular has surpassed the maximum call stack size, resulting in a Range Error

I am facing an issue while trying to include machine detail and a button bar in my app. Interestingly, this setup has worked perfectly fine in other parts of the application but is causing errors in the core module. Here is the error message main.ts impo ...

Is there a way to transform my existing Angular form layout so that it can effortlessly capture pre-loaded data sourced from an API using reactive form

As I work on creating a form to update user details using Angular, I am looking to enhance the current structure to automatically pre-fill all input fields with data when the page loads. component.ts file constructor( private fb:FormBuilder, private rout ...

JavaScript alert box

I'm fairly new to the world of web development, with knowledge in CSS & HTML and currently learning TypeScript. I'm attempting to create a message icon that opens and closes a notifications bar. Here's where I'm at so far: document.getE ...

Steer clear of utilizing Number() when working with scientific notation

I am attempting to perform the following task Number("0.00000000000122") yields 1.22e-12 However, my goal is to convert that number from a String to a Number. console.log(Number("0.00000000000122")) ...

Issue with accessing the 'subscribe' property in nested calls within Angular 2 due to it being undefined

I am trying to implement a subscription in company-list.component using the method getCompanies() from the company.service. However, I am encountering the following error: Cannot read property 'subscribe' of undefined Here is the code snippet ...

Mastering Typescript lookup types - effectively limit the properties included in a merge operation with the Partial type

Exploring lookup types, I'm interested in creating a safe-merge utility function that can update an entity of type T with a subset of keys from another object. The objective is to leverage the TypeScript compiler to catch any misspelled properties or ...

Replace current element in Angular 2

I am looking to change the current element during routing instead of simply adding to it. Below is the code I am currently using: <router-outlet> <div class="=row" style="height:30%"></div> <div class="=row"> <a ...

A TypeScript export class that is created based on configuration parameters

As someone who has primarily worked with C#, TypeScript is a new and exciting challenge for me. I've been enjoying exploring what I can create quickly using Node/TypeScript. However, I've run into a syntax issue that I could use some help with. I ...

A static factory method within an abstract class

I am currently developing a class system using Typescript. The main structure consists of an abstract class called Component, which includes a static method called create(). This method is utilized on child classes to generate specific instances. abstract ...

Tips for maximizing the state value when using useSelector() in React

I need help improving the way I use the useSelector function. Below is the code in question: const { addressList, deleteUserAddress, favouriteAddress, userAddressAfterUpdate, details, tokens, } = useSelector((state: RootState) ...