investtools/extensible-duck

Unable to dispatch a creator from a creator within the same Duck

taranda opened this issue · 2 comments

Thank you for this excellent library. I recently ran into a problem when I try to dispatch a creator from another creator within the same duck. Here is my example:

    creators: ({ types, creators }) => {
      return ({
        get: (id) => {
            return (dispatch, getState) => {
              dispatch({
                // some stuff
              });
            });
          }
        },
        hydrate: () => {
          return (dispatch, getState) => {
            dispatch({
              //  some stuff
            });
          };
        },
        refresh () => {
          return (dispatch,  getState) => {
            dispatch(creators.hydrate());
            dispatch(creators.get());
          }
        }
      });
    },

When I dispatch dispatch( myDuck.creators.refresh() ) I get:

Error: TypeError: undefined is not an object (evaluating '_creators.hydrate')

It seems the creators key is not available inside the creators function. Since this is a constructed object, I assume it has not yet been created.

I've tried various patterns. However, I am unable to figure out how to obtain a reference to the created Duck from within the creators themselves.

I am using the thunk middleware.

Any ideas or workarounds for this?

Thank you.

@taranda, You would need to fetch the creators reference only post they are executed during the instance creation.

One way would be like below and it works, Making it bound to the instance during creation itself would need some change in the way creators are executed if im not wrong.

       refresh () => {
          return (dispatch,  getState) => {

            // define a getter to access the creators from the duck instance
            const getCreators = () => duck.creators

            const { hydrate, get } = getCreators()

            dispatch(hydrate()); // dispatch the intended creators
            dispatch(get());
          }
        }

@aga5tya, thanks for the answer. That did not work, but this did:

    creators: ({ types, creators }) => {
      const creators = {
        get: (id) => {
            return (dispatch, getState) => {
              dispatch({
                // some stuff
              });
            });
          }
        },
        hydrate: () => {
          return (dispatch, getState) => {
            dispatch({
              //  some stuff
            });
          };
        },
        refresh () => {
          return (dispatch,  getState) => {
            dispatch(creators.hydrate());
            dispatch(creators.get());
          }
        }
      };

      return creators;
    },

I think instantiating the creators object as a local variable seemed to make it work. When I reviewed the source code of the Duck constructor, the duck that is passed to creators is the a version of the object that does not yet contain the creators. The other elements (types, reducers, etc) are available.