playboxdesign
playboxdesign

Reputation: 1

NGRX Select returning Store not a value

catalogueSelection in Store Image

I have the data I require in state (catalogueSelection: searchTextResult & categoryCheckboxResult) and need to pass the string 'SearchTextResult' into one component and the Array 'categoryCheckboxResult' into another.

When I try to retrieve the required values I am retrieving the whole store. I have looked at numerous websites and entries here but getting very confused now.

Model:

export class SearchTextResult {
  searchTextResult: string;
}

export class CategoryCheckboxResult {
  categoryCheckboxResult:Array<CategoryCheckboxResult>;
}

Actions:

import { Action } from '@ngrx/store';
import { SearchTextResult, CategoryCheckboxResult } from 'app/@core/services/products/products.model';

export enum UserCatalogueSelectionTypes {
    AddSearchTextResult = '[SearchTextResult] AddResult',
    AddCategoryCheckboxResult = '[CategoryCheckboxResult] AddResult',
    GetSearchTextResult = '[SearchTextResult] GetResult',
}

export class AddSearchTextResult implements Action {
    readonly type = UserCatalogueSelectionTypes.AddSearchTextResult;
    constructor(public payload: SearchTextResult){
    }
}

export class AddCategoryCheckboxResult implements Action {
    readonly type = UserCatalogueSelectionTypes.AddCategoryCheckboxResult;
    constructor(public payload: CategoryCheckboxResult){
    }
}

export class GetSearchTextResult implements Action {
    readonly type = UserCatalogueSelectionTypes.GetSearchTextResult;
}

export type UserCatalogueSelectionUnion =
| AddSearchTextResult
| AddCategoryCheckboxResult
| GetSearchTextResult

Reducers:

import { SearchTextResult, CategoryCheckboxResult} from "app/@core/services/products/products.model";
import { UserCatalogueSelectionTypes,  UserCatalogueSelectionUnion} from "../actions/products.actions";


export interface UserCatalogueSelectionState {
 searchTextResult: SearchTextResult | null;
 categoryCheckboxResult: CategoryCheckboxResult | null;
}

export const initialState: UserCatalogueSelectionState = {
    searchTextResult: null,
    categoryCheckboxResult: null,
}

 
export function reducer(state:UserCatalogueSelectionState = initialState, action: UserCatalogueSelectionUnion ): UserCatalogueSelectionState{
    switch (action.type) {
        case UserCatalogueSelectionTypes.AddSearchTextResult: 
            return {
                ...state, 
                searchTextResult: action.payload,
            };
        
        case UserCatalogueSelectionTypes.AddCategoryCheckboxResult: 
            return {
                ...state, 
                categoryCheckboxResult: action.payload,
            };

        case UserCatalogueSelectionTypes.GetSearchTextResult: {
            return state;
        }
            
        default: {
            return state;
        }

    }
}

Selectors:

import { createSelector,createFeatureSelector } from "@ngrx/store";
import {UserCatalogueSelectionState} from '../../store/reducer/products.reducer';

export const fetchSearchTextResults = createFeatureSelector<UserCatalogueSelectionState>("searchTextResult");

export const fetchSearchTextResult = createSelector (
    fetchSearchTextResults,
    (state:UserCatalogueSelectionState) => state.searchTextResult.searchTextResult
);

export const fetchCatalogueCheckBoxResults = createFeatureSelector<UserCatalogueSelectionState>("catalogueCheckboxResult");

export const fetchCatalogueCheckBoxResult = createSelector (
    fetchCatalogueCheckBoxResults,
    (state: UserCatalogueSelectionState) => state.categoryCheckboxResult.categoryCheckboxResult
);

My Component 1

Observable:

public searchTextResult: Observable<String>;

Contructor: (part of)

private store: Store<fromCatalogueSelection.UserCatalogueSelectionState>

Code Snippet: (asking for the data)

this.searchTextResult = this.store.select('SearchTextResult');
console.log('TESTING SEARCH TEXT: ', this.searchTextResult);

Console:

TESTING SEARCH TEXT: Store {_isScalar: false, actionsObserver: ActionsSubject, reducerManager: >ReducerManager, source: Store, operator: DistinctUntilChangedOperator}

My Component 2

Observable

searchTextResult$: Observable<CatalogueSelectionActions.GetSearchTextResult>;

Code Snippet: (asking for the data)

this.searchTextResult$ = this.store.select('GetSearchTextResult');
console.log('TESTING SEARCH TEXT: ', this.searchTextResult$);

Console:

TESTING SEARCH TEXT: Store {_isScalar: false, actionsObserver: ActionsSubject, reducerManager: > ReducerManager, source: Store, operator: DistinctUntilChangedOperator}

I've given up on the Selectors for the moment. Any help much appreciated as I'm going a round in circles.

Upvotes: 0

Views: 1130

Answers (1)

Andres2142
Andres2142

Reputation: 2917

You are almost there, the value from the console log is the observable object, everytime you select something from the store, you will get the value wrapped within an observable. You just need to subscribe to it:

this.searchTextResult$ = this.store.select('GetSearchTextResult');
this.searchTextResult$.subscribe((yourData) => console.log(yourData));

Also, since you are working with selectors, use them, you don't have to write the state/selector name:

selector

...
export const fetchCatalogueCheckBoxResult = createSelector (
    fetchCatalogueCheckBoxResults,
    (state: UserCatalogueSelectionState) => 
      state.categoryCheckboxResult.categoryCheckboxResult
);

component

import * as YourSelectors from './store/something/selectors/yourthing.selectors'

...
...
this.searchTextResult$ = this.store
    .select(YourSelectors.fetchCatalogueCheckBoxResult)
    .subscribe(console.log);

Additionally, try to subscribe using the async pipe delegating that to your template html so you don't have to deal with the subscription in the code, for example:

component

...
export class Component {
  searchTextResult$!: Observable<any> // your data type here
...
...
this.searchTextResult$ = this.store
    .select(YourSelectors.fetchCatalogueCheckBoxResult)
} 

html

<ng-container *ngIf="(searchTextResult$ | async) as result">
  <p>Your result value: {{ result }}</p>
</ng-container>

Upvotes: 2

Related Questions