redux-orm / redux-orm

NOT MAINTAINED – A small, simple and immutable ORM to manage relational data in your Redux store.

Home Page:https://redux-orm.github.io/redux-orm/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Adding new tables, coupled with redux-localstorage

azz0r opened this issue · comments

Hello, bit of edge case.

I have a whole bunch of collections/tables. I use redux-localstorage so that users can return and carry on playing.

I register like this

Appearance.modelName = 'Appearance'
Brand.modelName = 'Brand'
Wrestler.modelName = 'Wrestler'

export const orm = new ORM({
  stateSelector: state => state.entities
})

orm.register(
  Appearance,
  Brand,
  Wrestler,
)

I am now adding extra tables but found that I get errors, such as:

Uncaught runtime errors:
×
ERROR
Cannot read properties of undefined (reading 'itemsById')
TypeError: Cannot read properties of undefined (reading 'itemsById')
    at Table.idExists (http://localhost:3000/static/js/bundle.js:152474:18)
    at reducer (http://localhost:3000/static/js/bundle.js:152559:28)
    at Array.reduce (<anonymous>)
    at Table.query (http://localhost:3000/static/js/bundle.js:152652:36)
    at query (http://localhost:3000/static/js/bundle.js:152226:20)
    at Session.query (http://localhost:3000/static/js/bundle.js:151983:26)
    at Function._findDatabaseRows (http://localhost:3000/static/js/bundle.js:150808:25)
    at Function.exists (http://localhost:3000/static/js/bundle.js:150738:25)
    at Function.idExists (http://localhost:3000/static/js/bundle.js:150724:17)
    at Function.upsert (http://localhost:3000/static/js/bundle.js:150691:16)
    at Function.reducer (http://localhost:3000/static/js/bundle.js:1865:15)
    at http://localhost:3000/static/js/bundle.js:154179:18
    at Array.forEach (<anonymous>)
    at defaultUpdater (http://localhost:3000/static/js/bundle.js:154176:30)

So Ive tried adding some detection and generation:

const rootReducer = combineReducers({
  entities: createReducer(orm),
})

const createIfNotReady = (args) => {
  const currentState = args.getState().entities;
  // new collections
  const keys = ['Tournament', 'Ledger', 'Contract', 'Mail', 'Notification', 'Rumble', 'ArenaShow', 'ContractWrestler', 'Contract']

  if (!currentState.Tournaments) {
    keys.forEach(key => {
      if (!currentState[key]) {
        currentState[key] = {
          indexes: {},
          items: {},
          itemsById: {},
          meta: { maxId: 0 }
        }
      }
    })

    return (payload) => {
      return payload
    }
  }
}

const composeEnhancers =
  (window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ &&
    window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({
      trace: true,
      traceLimit: 25,
    })) ||
  compose

const store = createStore(
  rootReducer,
  composeEnhancers(
    applyMiddleware(thunk),
    applyMiddleware(createIfNotReady),
    persistState(),
  )
)

With no such luck to bypass the errors. If there a way to invoke and create the missing tables on detection? Any help greatly appreciated

If I step through the branch is undefined so perhaps i need to register sooner?
Screenshot 2023-12-02 at 12 12 10

Eample of a model

import { Model as ORMModel, attr, fk } from 'redux-orm'
import { Types } from '@fedsim/actions'
import { getId } from '@fedsim/helpers'

export default class Model extends ORMModel {
  static get fields() {
    return {
      id: attr(),
      image: attr({ getDefault: () => '' }),
      showId: fk({
        to: 'Show',
        as: 'show',
        relatedName: 'ArenaShow'
      }),
    }
  }
  static reducer(action, Arena, session) {
    let item
    switch (action.type) {
      default:
        break
      case Types.RESET:
      case Types.RESET_ARENAS:
        session.Arena.all()
          .toModelArray()
          .forEach(item => item.delete())
        break
      case Types.GENERATE_ARENAS:
        action?.payload?.forEach(newItem => {
          session.Arena.upsert(newItem)
        })
        break
      case Types.ADD_ARENA:
        const id = action?.payload?.id || getId()
        Arena.upsert({ id, ...action.payload })
        break
      case Types.UPDATE_ARENA:
        item = Arena.withId(action.payload.id)
        item.update(action.payload)
        break
      case Types.DELETE_ARENA:
        Arena.withId(action.payload.id).delete()
        break
    }
  }
}