Connecting to Redux Dev Tools from Node Based App - redux

I have a React/Redux app, running from Node with React-Blessed. It's materially the same as React DOM:
const screen = blessed.screen({..})
export function start () {
render(<Provider store={store}> <App /> </Provider>, screen);
}
Redux: I create the store, with the latest Redux-Toolkit methods. I'm following the instructions for remote access from Remote Redux Devtools
process.env['NODE_ENV'] = 'development';
import devToolsEnhancer from 'remote-redux-devtools';
const store = configureStore({
reducer: {
reducer
},
devTools: false, /* have also tried setting to true */,
enhancers: devToolsEnhancer
})
I run the node app, and attempt to connect with the Redux Chrome Extension (enabled extension permissions, localhost:8000 in the settings tab).
My state shows undefined... (I have ample initial state and reducers which should at least be visible)
Does anyone have any suggestions or know if I'm missing something?

Related

Runtime configs in nextjs

I'm trying to setup my nextjs app to use runtime configurations. Basically, I have an endpoint url that needs to be available trough docker env vars.
I configured following these docs but it isn't working. My app still using default values from .env file. Could anyone help to understand what I missed or did wrong?
Thanks!
docs:
https://nextjs.org/docs/api-reference/next.config.js/runtime-configuration
https://nextjs.org/docs/advanced-features/custom-app
steps:
1- added to my next.config.js
publicRuntimeConfig: {
NEXT_PUBLIC_BACKEND_HOST: process.env.NEXT_PUBLIC_BACKEND_HOST,
},
2- retrieved config in my pages
const { publicRuntimeConfig } = getConfig()
const baseURL = publicRuntimeConfig.NEXT_PUBLIC_BACKEND_HOST
3- created a custom app to setup getInitialProps
Runtime configuration won't be available to any page (or component in a page) without getInitialProps.
import App from 'next/app'
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
MyApp.getInitialProps = async (appContext) => {
const appProps = await App.getInitialProps(appContext);
return { ...appProps }
}
export default MyApp
Everything seems fine in your code, tested in a fresh project and everything worked correctly. Therefore I think the issue is that you don't actually have NEXT_PUBLIC_BACKEND_HOST env var set when you're running next start. Btw, you don't need to use the NEXT_PUBLIC prefix in this kind of usage. If you want build time args you can use NEXT_PUBLIC_ prefix to have the var be available both client and server side by just using process.env.NEXT_PUBLIC_ anywhere. Note that in that case the value will be inlined at build time, so the env var needs to be present during build.

Changing the state management system of existing quasar application from vuex to pinia

Tried this link and created my first store in Quasar using Pinia, I also needed to change the .quasar/app.js manually to add the Pinia store and to make Pinia functional.
import { Quasar } from 'quasar'
import { markRaw } from 'vue'
import RootComponent from 'app/src/App.vue'
import createStore from 'app/src/stores/index'
import createRouter from 'app/src/router/index'
export default async function (createAppFn, quasarUserOptions) {
// Create the app instance.
// Here we inject into it the Quasar UI, the router & possibly the store.
const app = createAppFn(RootComponent)
app.config.devtools = true
app.use(Quasar, quasarUserOptions)
const store = typeof createStore === 'function'
? await createStore({})
: createStore
app.use(store)
const router = markRaw(
typeof createRouter === 'function'
? await createRouter({store})
: createRouter
)
// make router instance available in store
store.use(({ store }) => { store.router = router })
// Expose the app, the router and the store.
// Note that we are not mounting the app here, since bootstrapping will be
// different depending on whether we are in a browser or on the server.
return {
app,
store,
router
}
}
But the problem is .quasar/app.js is re-written with default contents as soon as quasar dev is executed and again I don't have access to the Pinia stores anymore.
As I said this application was based on vuex formerly.
Make sure you have the index file for pinia.
In "src/stores/index.js"
import { store } from 'quasar/wrappers'
import { createPinia } from 'pinia'
/*
* If not building with SSR mode, you can
* directly export the Store instantiation;
*
* The function below can be async too; either use
* async/await or return a Promise which resolves
* with the Store instance.
*/
export default store((/* { ssrContext } */) => {
const pinia = createPinia()
// You can add Pinia plugins here
// pinia.use(SomePiniaPlugin)
return pinia
})
Try checking quasar info
quasar info
Notice #quasar/app-webpack and vuex.
If you are using #quasar/app, try to move to #quasar/app-webpack by upgrading quasar.
quasar upgrade -i
If you have vuex installed in your quasar info output, try to remove it.
npm uninstall vuex
In your package-lock.json, look for "node_modules/vuex" and delete the key and value.
Then delete your "node_modules" folder and run npm i
After that, run quasar clean.
You may try creating a Pinia store via quasar command to validate it.
quasar new store <store_name>
It should generate a pinia store instead of vuex store.
Problem is older version of #quasar/app-webpack package. It got support for Pinia since v3.4.0. Check release notes here. So basically upgrade this package.
Run quasar upgrade -i and then quasar new store <store_name> [--format ts]
It will create a stores/ directory with pinia.
In my case i didn't need to edit any special files, simply replace the index.js in the stores folder. To get quasar CLI to then use pinia when running quasar new store I had to use quasar clean and just like that I had fully transitioned.
My solution was to remove and reinstall node_modules

pouchdb-adapter-cordova-sqlite works locally but is not syncing

I have an issue using cordova-sqlite adapter in PouchDB. It works perfect locally (I can create, update and delete docs) but is not able to sync from/to any remote CouchDB server. I tried both IBM Cloudant and a CouchDB server of my own.
If I use IDB adapter instead it works like a charm, but when I change to SQLite is when it cannot sync properly.
This is how I use it (in my case inside a Vue app):
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import PouchDB from 'pouchdb'
...
Object.defineProperty(Vue.prototype, '$pouch', { value: PouchDB }); //this is to be able to use $pouch in any Vue component later on
...
var PouchAdapterCordovaSqlite = require('pouchdb-adapter-cordova-sqlite');
PouchAdapterCordovaSqlite.use_prefix = true; // use the legacy '_pouch' prefix. I tried both with and without this option
PouchDB.plugin(PouchAdapterCordovaSqlite);
...
this.db = new this.$pouch('todos', { adapter: 'cordova-sqlite', location: 'default', androidDatabaseImplementation: 2 });
console.log('PouchDB adapter: ' + this.db.adapter); //it returns 'cordova-sqlite'
let remoteCouch='http://myserveraddress.com:5984/todos'; //todos is the remote database, with CORS enabled and set as public so no user/pass is needed
this.$pouch.sync('todos', remoteCouch, {
live: true,
retry: true
}).on('change', function (info) { console.log('change:' + info}).on('paused', function (err) {//...//}).on --- and so on with 'active', 'denied', 'complete' and 'error'
and later in one Vue component I use this (where this.db refers to the database and this.todos is used to show results on screen:
mounted() {
this.list();
this.db
.changes({
since: "now",
live: true
})
.on("change", this.list);
},
methods: {
list: function() {
let self = this;
this.db.allDocs({ include_docs: true, descending: true }, function(
err,
doc
) {
self.todos = doc.rows;
});
}
}
As I mentioned before it works with IndexedDB but not with SQLite adapter (I used both cordova-sqlite-storage and cordova-plugin-sqlite-2 with same results). Everything starts after deviceready event and sqlite is loaded properly (I am able to use window.sqlitePlugin).
And when it comes to Cordova config.xml I ensured to define this:
<plugin name="cordova-plugin-whitelist"/>
<access origin="*"/>
<allow-intent href="http://*/*"/>
<allow-intent href="https://*/*"/>
...
<plugin name="cordova-plugin-sqlite-2" spec="*"/>
Any clue? I really need to use SQLite instead of IDB because my app will store big amount of data, and I also need an offline-first approach, that's why I use PouchDB.
Another test that I tried was to create a SQLite database manually from my app and it also works, so it seems that the problem is related to pouchdb-adapter-cordova-sqlite.
Screenshot with IDB:
result with idb
And screenshot with SQLite:
result with sqlite
Thanks in advance!
Solved!
The problem was here:
this.$pouch.sync('todos', remoteCouch, {...
It has to be changed to:
this.db.sync(remoteCouch, {...
So it was pointing to pouchdb object instead of the database instance.
I hope it helps someone.
Regards!

What is PERFORM_ACTION action type inside redux?

Inside my Redux store I recently started getting PERFORM_ACTION actions, which wrap my actual actions as follows:
{
type: PERFORM_ACTION,
action: {
type: REAL_ACTION,
payload: 123
}
}
I was not able to find any answer to this pattern neither in the documentations, nor in Google. The only suggestions that Google included were just references to this type of action without any explanation of what is it and why does it appear in applications.
So, what is this action?
redux dev tool extension wrap your actions with it's own action, what you can do is change the order of the middlewares load,
const store = createStore(
rootReducer,
compose(
applyMiddleware(
/* ---- middlewares ---- */
),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
)
);
if you place the the redux devtools middleware before your middlewares, you will get the warped action.

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