Search code examples
reduxreselectnormalizr

Transform entity / normalized response


I wonder where is a good place to transform a response entity(ies) before it is set in my Redux state.

Example

  • I have a chat_message entity
  • It has a read boolean property sent by the server
  • I need to compute a new unread boolean property = !message.read && message.user_id !== currentUser.id

Questions

  1. Do I compute this new attribute in a getChatMessages selector (reselect)?
  2. Do I compute this new attribute before I set the normalized response in my state? – Hence my question "Transform"
  3. Do I just calculate it in my Component, but this (simple) logic is not shared and duplicated all over the place...
  4. Do I send the unread attribute from the server...

Notes

  • unread attribute example is a simplified example.
  • I don't like solution 1., cause you need to share this logic between selectors anyway. So you might have a isMessageUnread helper function shared by getLastChatMessage, getChatMessages selectors. I also don't like selectors doing too much logic.
  • I would lean towards solution 2. New unread attribute is computed only when receiving response.
  • Solution 3. is my current lazy solution (with experiments here and there but nothing conclusive really)
  • I don't like solution 4., these attributes are more UI-related than backend-related.
  • If using solution 2., I feel like reducers is not a good place to do this tranformations. Might be easy for simple entities, but what about "heavy" transformation (iterating over collections, checking relationships, etc) ? I would prefer to put that new logic outside of: selectors, reducers, and entities. Kinda like a normalizr "plugin" / interceptor / transformer / post-processor...

Solution

  • Normalizr provides the processStrategy option:

    Strategy to use when pre-processing the entity. Use this method to add extra data, defaults, and/or completely change the entity before normalization is complete.