Cant create connected containers or enhancers for griddle - redux

I'm trying to create an Enhancer for griddle v1.6.0.
I am getting this error:
Uncaught Error: Could not find "store" in either the context or props
of "Connect(Row)". Either wrap the root component in a , or
explicitly pass "store" as a prop to "Connect(Row)".
Here is my Enhancer
import { connect } from 'react-redux';
import { selectors } from 'griddle-react';
const { rowDataSelector } = selectors;
export default connect((state, ownProps) => ({
hello: 'world!',
RDZ: rowDataSelector(state, ownProps)
}));
I have a similar problem if I try to create my own Container
EDIT
It appears that the connect is actually connecting to my app's store (which I haven't added a provider for) instead of griddle's internal store. I'm not sure how to access griddle's internal store in an enhancer, or container... Maybe I am missing something here, should I be adding selectors instead?

This a current limitation/bug with Griddle (I think).
I worked around this by passing by data from the app redux to simple component, then that component hands the data to Griddle.
This is not ideal, but works for now.
This discussion maybe of some help.
https://github.com/GriddleGriddle/Griddle/issues/647

Related

Handling namespaced modular approach on PINIA, Vue3+Typescript

normally I was using namespaced vuex. But I am deciding to quit vuex because Pinia has the vue core team support. I think it's better for the future developements. Now I am creating store with a modular approach but couldn't really understand how to handle that part on typescript project.
let's say I have a user interface.
interface User {
email: string,
username: string,
}
export default User;
and in store/modules/state.ts I am calling the Type and creating a user state.
import User from "../../types/User"
export const state = () => {
return {
user: {} as User | null,
};
}
and in store/modules/index.ts I should import the state. And make the namespace: true then export it for the defineStore() for pinia store.
import {state} from "./state"
export default {
namespace: true,
state,
}
in store/index.ts
import {defineStore} from "pinia"
import {data} from "./modules"
export const Store = defineStore(data)
okay above, namespace part I use the vuex way. But what is the right approach for the pinia. Additionally, getters and actions as well. How should export and use them.
According to official Pinia docs:
Vuex has the concept of a single store with multiple modules. These modules can optionally be namespaced and even nested within each other. The easiest way to transition that concept to be used with Pinia is that each module you used previously is now a store.
So now you should think about each vuex module as an separated pinia store. Looking at your example it could look like this. create file in store/modules/index.ts and paste:
import { defineStore } from "pinia";
import state from "store/modules/state.ts"; // Assuming that it's path to user state
export const useUserStore = defineStore('some/vuex/module/name', {
state: state,
getters: {
// your getters here, check the Offical Pinia above
},
actions: {
// your actions and mutations here, also check the offical Pinia Docs
}
})
If you want to split getters, actions and state into multiple files, there is discussion on offical repo issue where I provided example, that is working for me. Here is a link

Redux Persist + Redux toolkit $CombinedState error

I'm trying to add redux persist to redux toolkit but for some reason I get an Exported variable 'store' has or is using name '$CombinedState' from external module ".../node_modules/redux/index" but cannot be named. error on vscode.
This is my store configuration file with the added persist config, which if I remove, works fine.
import { configureStore } from "#reduxjs/toolkit";
import { persistReducer } from "redux-persist";
import storage from "redux-persist/lib/storage";
import { createEpicMiddleware } from "redux-observable";
import rootEpic from "onsite/redux/rootEpic";
import rootReducer from "onsite/redux/rootReducer";
const epicMiddleware = createEpicMiddleware();
const persistConfig = {
key: "root",
storage: storage,
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
// Line that shows error
const store = configureStore({
reducer: persistedReducer,
middleware: [epicMiddleware],
});
export default store;
epicMiddleware.run(rootEpic);
Other things I have tried are putting the combineReducers declaration (from rootReducerimport) into the same file or converting the file into plain javascript, with same or similar results. For some reason typescript decides to still haunt me on a javascript file :)
The code still runs, so I'm tempted to leave it like that, but I would like to get rid of it.
I had the same issue, and here's what I figured out:
You need to include Store from redux, and use it as your type definition for your own store return value. Short answer:
import { Store } from 'redux';
[...]
const store:Store = configureStore([...])
[...]
export default store;
Longer answer:
As I understand it, what was happening is that Store type uses $CombinedState as part of its definition. When configureStore() returns, it inherits the State type. However since State is not explicitly used in your code, that now means that your code includes a value that references $CombinedState, despite it not existing anywhere in your code either. When you then try to export it out of your module, you're exporting a value with a type that doesn't exist within your module, and so you get an error.
You can import State from redux (which will in turn explicity cause your code to bring in $CombinedState), then use it to explicitly define store that gets assigned the return of configureStore(). You should then no longer be exporting unknown named types.
You can also be more specific with your Store type, as it is a generic:
const store:Store<RootState>
Although I'm not entirely sure if that would be a circular dependency, since your RootState depends on store.
Adding a
import { $CombinedState } from '#reduxjs/toolkit'
in that file should usually resolve that error.

What is the use of referencing appState/rootState in feature store

Trying to understand the ngrx example app, got stuck and unable to figure out its use case.
What is the importance of State in the below code taken from ngrx-example-app
export interface State extends fromRoot.State {
[booksFeatureKey]: BooksState;
}
/** Provide reducer in AoT-compilation happy way */
export function reducers(state: BooksState | undefined, action: Action) {
return combineReducers({
[fromSearch.searchFeatureKey]: fromSearch.reducer,
[fromBooks.booksFeatureKey]: fromBooks.reducer,
[fromCollection.collectionFeatureKey]: fromCollection.reducer,
})(state, action);
}
Doing this has no run-time differences, it's only to make typescript aware you "have" a root state.
This is needed to make typescript happy if you access root state or root selectors from within your feature state selectors.

How to get access to native Firebase object when using angularfire2?

I'm using AngularFire2 (2.0.0-beta.2) incombination with angular2 (2.0.0-rc.4). I'd like to get access to the native firebase object (not the AngularFire root object) from Angularfire2.
Within my component, I want to make calls like:
firebase.auth().currentUser.updateEmail("user#example.com")
where firebase is the native firebase object, like that you get from the fragment below:
<script src="https://www.gstatic.com/firebasejs/3.1.0/firebase.js"></script>
<script>
// Initialize Firebase
// TODO: Replace with your project's customized code snippet
var config = {
apiKey: "apiKey",
authDomain: "projectId.firebaseapp.com",
databaseURL: "https://databaseName.firebaseio.com",
storageBucket: "bucket.appspot.com",
};
firebase.initializeApp(config);
</script>
But I don't understand how to setup my angular2 component so that the firebase object is visible within it. Probably a very simple problem to solve, but I don't know how to solve -- I'm not an angular2 expert. I was hoping there would be and AngularFire api to get the object, but there is not.
Also, the reason that I'm trying to do this is that I don't think the angularfire2 api's are complete yet (thats understandable as its still in beta) and I'm trying to work around this. For example I want to update the users email address or password, or send them the forgotten password email. None of this functionality seems to exist yet in AngularFire2, so I'm trying to implement using the native Firebase object.
If you're reading this in September 2016 onwards, this approach might sound good to you.
See the code for superior understanding:
import { Component, Inject } from '#angular/core';
import { AngularFire, FirebaseApp } from 'angularfire2';
#Component({
templateUrl: 'app/auth/resetpassword.component.html'
})
export class ResetpassComponent {
public auth: any;
constructor(private af: AngularFire, #Inject(FirebaseApp) firebaseApp: any) {
this.auth = firebaseApp.auth()
console.log(this.auth);
}
// formData.value.email = 'your#email.com';
onSubmit(formData) {
if(formData.valid) {
console.log('Sending email verification');
this.auth.sendPasswordResetEmail(formData.value.email)
.then( (response) => {
console.log('Sent successfully');
})
.catch( (error) => {
console.log(error);
})
}
}
}
In English:
Import Inject and FirebaseApp
Make available in your component
Start using all the native javascript SDK functions and methods, such as sendPasswordResetEmail()
Doing a auth. doesn't autocomplete with the available methods and functions, so you might need the docs close to you, such as this: https://firebase.google.com/docs/auth/web/manage-users
Any thanks? Give to #cartant : https://stackoverflow.com/a/39069813/1757321
I'm going to try and answer my own question. Let me first say that I'm sure my answer is not the most elegant solution, I'm not yet a javascript/typescript/angular expert. But my answer does work -- even if I don't completely understand.
I used angular-cli to setup my project which is based on angular2 and the latest firebase. Apparently when you use this to setup your project there is a global object created with the name "firebase" in existence. One way to make it visible within your angular 2 component is to put this declaration at the global level in you component (right after the import statements and before your class declaration).
declare var firebase : any;
After you do this the global firebase object is available for use in your component.
RanchoSoftware's solution did not work for me, i used
import {AngularFireModule} from "angularfire2";
import *as firebase from 'firebase';
within the imports in the app.module.ts file
found here:
https://github.com/angular/angularfire2/issues/445

React + MobX - not re-rendering update to state

I've setup a new sample/boilerplate project for testing out using Meteor with React & MobX (using Mantra architecture). The project is at https://github.com/markoshust/mantra-matui-mobx
I'm having an issue where the state change of the State.header.title property is not properly reflecting the updated state change on re-render.
My state is built by pulling in simple objects:
https://github.com/markoshust/mantra-matui-mobx/blob/master/client/modules/core/stores/route.js
Into one master observable object:
https://github.com/markoshust/mantra-matui-mobx/blob/master/client/main.js#L8
I'm listing for route change and calling an action to update state:
https://github.com/markoshust/mantra-matui-mobx/blob/master/client/modules/core/reactions/route.js#L10
This action updates state:
https://github.com/markoshust/mantra-matui-mobx/blob/master/client/modules/core/actions/route.js#L5
The console is logging out proper state change, so the state is being updated properly. However, the component is not being re-rendered with the updated state (this line is console.log'ing old state val):
https://github.com/markoshust/mantra-matui-mobx/blob/master/client/modules/core/containers/Header.js#L6
I'm seeing the 'updating...' message, so the component is re-rendering, but it appears to still be pulling in the old state. I did add observer to all of my react components:
https://github.com/markoshust/mantra-matui-mobx/blob/master/client/modules/core/components/Header.js
I needed to create a custom composer for MobX. I added a listen for autorun to re-compose the component.
https://github.com/markoshust/mantra-matui-mobx/blob/master/client/modules/core/libs/with_mobx.js
import { compose } from 'mantra-core';
import { autorun } from 'mobx';
export default function composeWithMobx(fn, L, E, options) {
const onPropsChange = (props, onData) => {
const reactiveFn = () => fn(props, onData);
autorun(reactiveFn);
return reactiveFn();
};
return compose(onPropsChange, L, E, options);
}

Resources