Angular и NGRX: фильтрация селектора с использованием сущности NGRX

Я пытаюсь отфильтровать данные полезной нагрузки по свойству.

 //reducer.ts

  case MessagesActionTypes.LOAD_Message_SUCCESS: {
      console.log('reducer='+ 
      JSON.stringify(action.payload.Messages));//receiving data here
      return adapter.addAll(action.payload.Messages, state);
    }

    export const getSelectedMessageId = (state: MessageState) => state.selectedMessageId;

// get the selectors
const { selectIds, selectEntities, selectAll, selectTotal } = adapter.getSelectors();


// select the array of Messages
export const selectAllMessages = selectAll;

Ниже селектор

 //     Selector.ts

export const selectHomeQueues = createSelector(
  fromReducer.selectAllMessages,
 (messages) => messages.filter(message => message.queue === 'HOME')
 );

Я получаю данные в редукторе, но получаю ошибку в селекторе во время выполнения ERROR TypeError: Cannot read property 'map' of undefined

Примечание. Мне не удалось найти ни одного примера фильтрации в селекторах сущностей NGRX.

Как мы фильтруем селекторы в сущности NGRX?


person prabhat gundepalli    schedule 23.10.2018    source источник


Ответы (3)


У меня была точно такая же проблема. Вам нужно немного изменить свой селектор, чтобы:

export const selectHomeQueues = createSelector(
  selectAllMessages,
 (messages) => messages.filter(message => message.queue === 'HOME')
 );

Где selectAllMessages - это селектор, который вы определили просто как:

export const selectAllMessages = createSelector(
  fromReducer.selectAllMessages
 );

Первоначально мы пытались сделать это через адаптер, и я подозреваю, что мы где-то допустили небольшую ошибку или заблуждение.

person ldgorman    schedule 14.05.2019

Ошибка «Невозможно прочитать карту свойства undefined» предполагает, что вы получаете ошибку в другом месте, потому что в коде, который вы указали в своем вопросе, мы нигде не видим map.

В вашем селекторе вы фильтруете messages, и он пропускает header, который никогда не используется. Кажется, что вы фильтруете не отдельные сообщения, а очереди сообщений, поэтому:

export const selectHomeQueues = createSelector(
  fromReducer.selectAllMessages,
 (messages) => messages.queue === 'HOME'
 );
person inorganik    schedule 23.10.2018

Думаю, можно так:

const getSelectHomeQueues = (store) => {
    return store.select(fromReducer.selectAllMessages)
        .filter(message => message.queue === 'HOME')
}

Везде, где вы хотите его использовать:

getSelectHomeQueues(this.store).subscribe(...)
person Balázs Takács    schedule 23.10.2018
comment
Я хочу иметь специальный селектор фильтров в файле селекторов. const getSelectHomeQueues определяется в селекторе или компоненте? - person prabhat gundepalli; 23.10.2018
comment
Среди селекторов. - person Balázs Takács; 23.10.2018
comment
Возможно, я что-то упускаю. Как импортировать хранилище в селекторы, если у него даже нет конструктора? - person prabhat gundepalli; 23.10.2018
comment
Давайте поиграем с примером. У вас есть компонент, и вы вводите store в конструктор. Также вы хотите использовать getSelectHomeQueues в этом компоненте, чтобы просто вставить второй фрагмент кода. Вам не нужно импортировать хранилище в селекторы. Вызывая getSelectHomeQueues, вы передаете ссылку на магазин. - person Balázs Takács; 23.10.2018
comment
получение ошибки `TypeError: store.select (...). filter is not a function` в операторе возврата селектора - person prabhat gundepalli; 23.10.2018
comment
Если вы используете rxjs 6 или выше, вам нужно передать его по конвейеру. - person Balázs Takács; 23.10.2018
comment
Я пытаюсь заставить это работать. Снял фильтр и запустил. Теперь это дает мне core.js:1542 ERROR TypeError: Cannot read property 'map' of undefined at entity.js:27 at store.js:528 - person prabhat gundepalli; 23.10.2018
comment
Не могли бы вы создать стекблиц? - person Balázs Takács; 23.10.2018