Guldborg92
Guldborg92

Reputation: 176

Getting object instead of list from selecting the store with NgRx

I'm having problems retrieving an list from my state in the store, because the list is wrapped around with an object.

Here is my code

beer-list.component.ts

@Component({
  selector: 'app-beer-list',
  templateUrl: './beer-list.component.html',
  styleUrls: ['./beer-list.component.css']
})
export class BeerListComponent implements OnInit {
  public beers$: Observable<Beer[]>;
  
  constructor(private store: Store<BeerState>) {
  }

  ngOnInit(): void {
    this.beers$ = this.store.select((state: BeerState) => state.beers);
    this.store.dispatch(getBeersOnTap());
  }

beer.actions.ts

export const getBeersOnTap = createAction(
  '[Beer List] Get beers'
);
export const getBeersOnTapSuccess = createAction(
  '[Beer List] Get beers succeeded',
  props<{beers: Beer[]}>()
);
export const getBeersOnTapFailed = createAction(
  '[Beer List] Get beers failed'
);

beer.reducers.ts

export interface BeerState {
  beers: Beer[];
}

export const initialState: BeerState = {
  beers: []
};

export const beerReducer = createReducer(
  initialState,
  on(getBeersOnTapSuccess, (state, {beers}) => ({...state, beers: beers}) // Payload comes from an effect
));

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

What I'm retrieving from selecting beers from the store:

{
  beers: {
    beers: [
      ...

Upvotes: 0

Views: 51

Answers (2)

Guldborg92
Guldborg92

Reputation: 176

Ok. I finally figured it out. I needed to adjust my state tree and add some selectors to select the beers from the store.

Here is my updated NgRx code where changes are commented:

beer-list.component.ts

@Component({
  selector: 'app-beer-list',
  templateUrl: './beer-list.component.html',
  styleUrls: ['./beer-list.component.css']
})
export class BeerListComponent implements OnInit {
  public beers$: Observable<Beer[]>;
  
  constructor(private store: Store<AppState>) {
  }

  ngOnInit(): void {
    this.beers$ = this.store.select(selectBeers); // Using selector here
    this.store.dispatch(getBeersOnTap());
  }
}

app.state.ts (new file)

export interface AppState {
  beerState: BeerState
}

beer.selectors.ts (new file)

const selectBeerState = (state: AppState) => state.beerState;

export const selectBeers = createSelector(
    selectBeerState,
    (state) => state.beers
)

Upvotes: 0

timdeschryver
timdeschryver

Reputation: 15505

The beerReducer is probably added to a beers feature? So you will have to select the beer state first.

   this.beers$ = this.store.select((state: AppState) => state.beers.beers);

Upvotes: 1

Related Questions