skip to Main Content

recently i’ve been trying to learn ngrx and i am following a guide. The code of the guide i’m following is the same as mine, but i am getting this error:

Type 'Observable<void>' is not assignable to type 'Observable<IComment[]>'.
  Type 'void' is not assignable to type 'IComment[]'.

I am getting the error inside the constructor of the commentComponent at both isLoading$ and comments$:

import { Component, OnInit } from '@angular/core';
import { Store, select } from '@ngrx/store';
import { Observable } from 'rxjs';
import * as CommentActions from './store/comment.actions'
import { AppStateInterface } from 'src/app/types/appState.interface';
import { commentsSelector, isLoadingSelector } from './store/comment.selector';
import { IComment } from 'src/app/shared/interfaces/comment';


@Component({
  selector: 'app-comment',
  templateUrl: './comment.component.html',
  styleUrls: ['./comment.component.css'],
})
export class CommentComponent implements OnInit  {
  isLoading$: Observable<boolean>
  comments$: Observable<IComment[]>;

  constructor(private store: Store<AppStateInterface>) {
    this.isLoading$ = this.store.pipe(select(isLoadingSelector))
    this.comments$ = this.store.pipe(select(commentsSelector))
  }

  
  ngOnInit(): void {
    this.store.dispatch(CommentActions.getComments())
  }


}
 

I think my problem lies somewhere in the selectors but I cant find it.

import { createSelector, select } from '@ngrx/store';
import { AppStateInterface } from 'src/app/types/appState.interface';

export const selectFeature = (state: AppStateInterface) => state.comments;

export const isLoadingSelector = createSelector(selectFeature, (state) => {
  state.isLoading;
});

export const commentsSelector = createSelector(selectFeature, (state) => {
  state.comments;
});

export const errorSelector = createSelector(selectFeature, (state) => {
  state.error;
});

Since its too much code, i will paste the repo here so anyone can check it out. The ngrx code is mainly in the ./movies/comment/store folder. https://github.com/kris34/Movies/tree/main/Client/movies-project/src/app/movie

3

Answers


  1. You’re missing a return statement in your selector, hence the void instead of IComment[]:

    export const commentsSelector = createSelector(selectFeature, (state) => {
      return state.comments;
    });
    

    Or use the implicit return by removing the curly:

    export const commentsSelector = createSelector(selectFeature, (state) => 
      state.comments;
    );
    
    Login or Signup to reply.
  2. You have incorrect selector definitions. In your current selector definitions, you are not returning any values, which results in the type being inferred as void. Try to modify your selector functions to return the appropriate values

    e.g.

    import { createSelector, select } from '@ngrx/store';
    import { AppStateInterface } from 'src/app/types/appState.interface';
    
    export const selectFeature = (state: AppStateInterface) => state.comments;
    
    export const isLoadingSelector = createSelector(selectFeature, (state) => {
      return state.isLoading; // Return the isLoading property
    });
    
    export const commentsSelector = createSelector(selectFeature, (state) => {
      return state.comments; // Return the comments property
    });
    
    export const errorSelector = createSelector(selectFeature, (state) => {
      return state.error; // Return the error property
    });
    
    Login or Signup to reply.
  3. As the other comment answer you need to return the comments. Here’s how it can look like:

    export const commentsSelector = createSelector(selectFeature, (state) => state.comments);
    

    Or alternatively, if you want explicit function body, then this:

    export const commentsSelector = createSelector(selectFeature, (state) => {
      state.comments;
    });
    

    I’m thinking you either missed this yourself, or maybe you don’t know how arrow functions work. As a reminder, if you do this:

    const myFn = state => state.comments;
    

    This means an "implicit return". After the => arrow, you directly write down an expression that’s returned out of the myFn function.

    If you opened the curly braces after the arrow (the () => { ... } version), then you have to explicitly return what you needed.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search