Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature Request: use an already created store. #19

Closed
dlmanning opened this issue Sep 4, 2015 · 14 comments
Closed

Feature Request: use an already created store. #19

dlmanning opened this issue Sep 4, 2015 · 14 comments

Comments

@dlmanning
Copy link

I'm aware I'm already pretty far out on a limb here, but my project uses both react (via ngreact) and angular. We've been using redux for the react part of the application, and I'm not working to bring it to the angular portion using your module. (Great work, btw!)

We already have a redux store, and would like to just share it between the react and angular portions instead of keeping two stores in parallel by sharing the reducers. Would that be as simple as adding a .useStore() method to ngReduxProvider?

@dlmanning
Copy link
Author

So, having looked at the source and seeing how this is actually implemented, I can see getting this to work is a little trickier than I thought. The digestMiddleware needs $rootScope. For my particular needs, I'm going to create the store in angular and pass it through ngReact into the Provider component.

Edit: Yup, that works.

@wbuchwalter
Copy link
Member

Hey David,
Yea creating the store in angular is your best bet, this how it is done in the counter example.
That said, removing createStoreWith is on my todo list, to add more flexibility, but I have yet to find a way to do that while still allowing injectable middlewares and not being painful to use.

@punmechanic
Copy link

Why the wontfix? is it because of the injectable middleware issue?

@reinseth
Copy link

@wbuchwalter: what if you remove the digest middleware altogether, and do $evalAsync in the connect function?

I see two benefits with this approach:

  1. Fewer calls to $evalAsync as there are more actions than there are actual state changes (which the connector takes care of to detect) - this will be a performance benefit, especially if you have lot's of actions which does not affect the state of the components (e.g. a ticker for an audio player that updates the current track/segment title on every position update).
  2. Flexibility: the store can be created outside of angular.

@alejandroiglesias
Copy link

I would like to use this feature as well to share a store between React and Angular. No work on this happened?

@mischkl
Copy link

mischkl commented Jan 24, 2017

I am interested in sharing the store between Angular 1 and Angular 2 (via ng2-redux). This is actually one of the main reasons I plan on using ng(2)-redux instead of ngrx, so that it integrates better with ng1 and eases the transition for a project that is being migrated. Is there an easy/recommended way of doing this?

@AntJanus
Copy link
Collaborator

AntJanus commented Aug 22, 2017

Hey all, I added this to the milestones for the 4.0.0 release. In the meantime, you can easily provide an existing store via an enhancer that runs first:

import myStore from '../shared/store'; // initial store setup using plain Redux

function storeProviderEnhancer() {
  return () => myStore;
}

// ... in AngularJS
$ngReduxProvider.createStoreWith(state => state, [], [storeProviderEnhancer]);

// ... in Angular using angular-redux/store
this.ngRedux.provideStore(store as Store<IAppState>);

@AntJanus AntJanus mentioned this issue Sep 13, 2017
9 tasks
@rshackleton
Copy link
Contributor

rshackleton commented Sep 21, 2017

@AntJanus using your example above seems to position the digest middleware first rather than last and this the digest loop is not updated at the correct time. Also it seems to end up causing two separate middleware chains if middleware have been configured on the original store.

http://redux.js.org/docs/faq/StoreSetup.html#is-it-ok-to-have-more-than-one-middleware-chain-in-my-store-enhancer-what-is-the-difference-between-next-and-dispatch-in-a-middleware-function

@AntJanus
Copy link
Collaborator

AntJanus commented Jan 4, 2018

Hey all, I'm trying to wrap my head around how this could be implemented. Would love some help here.

Here's currently what happens:

  1. we store all of the necessary stuff to create a store in createStoreWith
  2. on $get we create a new store with all that stuff we provided on createStoreWith, we add a digestMiddleware to the middleware chain which does the $rootScope.$evalAsync

I looked at angular-redux/store which wraps the store and subscribes to it. Each time we get new data, it gets pushed into the observable which then pushes to the components. We don't have that option, currently.

I'm trying to figure out how to run the $rootScope evaluation without using the middleware. The only way really to do that is to create a store enhancer around the existing store. The question is where to intercept.

I think the best way is to overwrite dispatch so that it runs on the original store and runs the $rootScope.$evalAsync right after the dispatch. But if there is a middleware that terminates the chain (like thunk), we'd evaluate $rootScope for no reason. My other worry has to do with how it plays with the Connector.

I'd love any input on this.

@derrickpelletier
Copy link
Contributor

@AntJanus re: your concern about evaluating $rootScope for no reason when a middleware terminates the chain, is your worry purely performance, or is there some other issue there?

@guillaumevincent
Copy link

maybe I'm missing something but this is something that already works no?

app.js

import store from "./store";

angular
  .module("app", [ngRedux])
  .config(["$ngReduxProvider",   $ngReduxProvider =>  $ngReduxProvider.provideStore(store)])

store.js

import { createStore, combineReducers, applyMiddleware } from "redux";
import thunk from "redux-thunk";

export const rootReducer = combineReducers({
  currentUser: currentUserReducer,
  config: configReducer
});

export default createStore(rootReducer, applyMiddleware(thunk));

@derrickpelletier
Copy link
Contributor

@guillaumevincent .provideStore() is actually introduced by the above merged PR. This ticket didn't get closed in the process.

@AntJanus can you close it up?

@guillaumevincent
Copy link

@derrickpelletier ack
Should we update the documentation and encourage the use of provideStore ?

@dpundir
Copy link

dpundir commented Jun 4, 2018

I have single page application of multiple pages in AngularJs.
I am creating store in root application:
$ngReduxProvider.createStoreWith(rootReducer)
In each multiple pages which are lazy loaded, i am doing again adding application level reducers:
$ngReduxProvider.createStoreWith(applicationReducer)
I want to include my application level reducers to the store when lazyload application.

Do we have example to achieve this? Any document link of this usage will help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests