redux-observables chain simple epics - redux-observable

From this issues thread > https://github.com/redux-observable/redux-observable/issues/33#issuecomment-342399904
I've extracted this helper:
const forkEpic = (epicFactory, ...actions) => {
const input$ = Observable.of(...actions);
const actions$ = new ActionsObservable(input$);
return epicFactory(actions$);
};
My question is, how to insert Epic dependencies on the epicFactory?
Epic dependencies in the form of https://redux-observable.js.org/docs/recipes/InjectingDependenciesIntoEpics.html
The main idea behind is (as discussesd un the issue) is chaining epics
The injected dependencies are undefined, and as said on this question, passing the dependencies director does not solve the issue. (https://github.com/redux-observable/redux-observable/issues/33#issuecomment-342399904)

Just for the record the answer > https://github.com/redux-observable/redux-observable/issues/33#issuecomment-342786804

Related

How to use remove() (Firebase SDK 9 web)

How to use "remove()" in SDK v9 web?
(context: I'm learning React Native (using Expo) and there's this todo app).
There are no examples in the documentation. Here is what I have:
// firebase
import app from "./firebaseConfig";
import {
getDatabase,
ref,
set,
push,
onValue,
remove,
child,
} from "firebase/database";
// etc
const db = getDatabase(app);
const taskListRef = ref(db, "tarefas/" + user);
const newTaskRef = push(taskListRef);
// etc
const handleDelete = (key) => {
remove(taskListRef).then(() => {
const findTasks = tasks.filter((item) => item.key !== key);
setTasks(findTasks);
});
};
So, this remove(taskListRef) is my problem. I don't know how to call it properly regarding the reference to the data location.
I've tried: remove(taskListRef.child(user)), remove(taskListRef.child(key)) etc... and a bunch of other similar things. The error always: wrong reference.
Here is the repo. Please, help. Thank you all in advance.
P.S.: hopefully I won't have to ask a similar question regarding update().

jest snapshot testing: how to ignore part of the snapshot file in jest test results

Problem: ignore some part of the .snap file test results
the question here: there are some components in my test that have a random values and i don't really care about testing them. is there any way to ignore part of my X.snap file? so when i run tests in the future it won't give me test fail results.
Now you can also use property matcher for these cases.
By example to be able to use snapshot with these object :
const obj = {
id: dynamic(),
foo: 'bar',
other: 'value',
val: 1,
};
You can use :
expect(obj).toMatchSnapshot({
id: expect.any(String),
});
Jest will just check that id is a String and will process the other fields in the snapshot as usual.
Actually, you need to mock the moving parts.
As stated in jest docs:
Your tests should be deterministic. That is, running the same tests multiple times on a component that has not changed should produce the same results every time. You're responsible for making sure your generated snapshots do not include platform specific or other non-deterministic data.
If it's something related to time, you could use
Date.now = jest.fn(() => 1482363367071);
I know it's quite old question but I know one more solution. You can modify property you want to ignore, so it will be always constant instead of random / dynamic. This is best for cases when you are using third party code and thus may not be able to control the non deterministic property generation
Example:
import React from 'react';
import Enzyme, { shallow } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
import Card from './Card';
import toJSON from 'enzyme-to-json';
Enzyme.configure({ adapter: new Adapter() });
describe('<Card />', () => {
it('renders <Card /> component', () => {
const card = shallow(
<Card
baseChance={1}
name={`test name`}
description={`long description`}
imageURL={'https://d2ph5fj80uercy.cloudfront.net/03/cat1425.jpg'}
id={0}
canBeIgnored={false}
isPassive={false}
/>
);
const snapshot = toJSON(card);
// for some reason snapshot.node.props.style.backgroundColor = "#cfc5f6"
// does not work, seems the prop is being set later
Object.defineProperty(snapshot.node.props.style, 'backgroundColor', { value: "#cfc5f6", writable: false });
// second expect statement is enaugh but this is the prop we care about:
expect(snapshot.node.props.style.backgroundColor).toBe("#cfc5f6");
expect(snapshot).toMatchSnapshot();
});
});
You can ignore some parts in the snapshot tests replacing the properties in the HTML. Using jest with testing-library, it would look something like this:
it('should match snapshot', async () => {
expect(removeUnstableHtmlProperties(await screen.findByTestId('main-container'))).toMatchSnapshot();
});
function removeUnstableHtmlProperties(htmlElement: HTMLElement) {
const domHTML = prettyDOM(htmlElement, Infinity);
if (!domHTML) return undefined;
return domHTML.replace(/id(.*)"(.*)"/g, '');
}
I used this to override moment's fromNow to make my snapshots deterministic:
import moment, {Moment} from "moment";
moment.fn.fromNow = jest.fn(function (this: Moment) {
const withoutSuffix = false;
return this.from(moment("2023-01-12T20:14:00"), withoutSuffix);
});

React Native + Redux: Where to put functions for 3rd party libraries?

I'm creating an ecommerce app that uses a geolocation library (https://github.com/transistorsoft/react-native-background-geolocation).
I have an orderState:
const ordersInitState = {
lineItems: [],
status: ORDER_STATUSES.AWAITING_CHECKOUT,
};
const ordersReducer = (prevState=ordersInitState, action) => {
switch(action.type) {
...
case actions.ORDERS.REMOVE_ITEM:
const lineItems = [...prevState.lineItems];
const indexToRemove = action.payload;
lineItems.splice(indexToRemove, 1);
const status = lineItems.length > 0 ? prevState.status : ORDER_STATUSES.AWAITING_CHECKOUT;
return {
...prevState,
status,
lineItems,
};
default:
return prevState;
}
}
export default ordersReducer;
As you can see, the client is allowed to remove items from their cart. If they end up removing everything, their order status will reset. If they do end up emptying their cart (lineItems.length === 0) I want to also run a simple line from the geolocation library:
BackgroundGeolocation.removeGeofence("blah");
Where would I put this? It feels wrong to do it in the reducer because it has nothing to do with state. It also isn't specific to one particular component, so putting it in one of my components doesn't make sense.
I'm still a bit new to redux so I'm not sure where to put non-state related methods.
The often used name for what you are looking for is called "side effects" middleware. In the abstract, you want to cause an effect in an external system (in this case, the geolocation library), when the application state changes.
There are many libraries for this use case. Some of the more popular ones are redux-saga and redux-loop. They are both good tools and help give structure to managing complicated side effects, but both come with a significant conceptual overhead, and should only be used when really needed.
If you want a quick and simple solution, you can create a plain JavaScript module that subscribes to your store changes and executes the side effects for you:
import store from '../your/redux/store;
let previousCount = 0;
store.subscribe(() => {
const count = store.getState().orders.lineItems.length;
if (count === 0 && previousCount > 0) {
// someone just emptied the cart, so execute side-effect
BackgroundGeolocation.removeGeofence("blah");
}
previousCount = count;
});
And then if you find yourself needing this type of solution repeatedly, you can reach for one of the libraries mentioned above.

Can RxJS/Most Observable be integrated?

I would like to be able to use an Observables library of sorts to integrate with other parts of my system.
It looks like having Observables streams would work nicely with gun. :)
Apart from using a library integration, another solution is to build your own Observables from Gun instances. See this codesandbox for example: https://codesandbox.io/s/pYj4OM8m1
const user$ = name => // returns a new observable
Observable.create(o =>
gun.get(name).on(v => {
o.next(v); // passes any new values to the observers
console.log(v);
}),
);
// now you can do rx stuff on the stream of values
user$('something'))
.map(({ name }) => ({ name: name.toUpperCase() }))
.filter(({ name }) => name.length > 0)
It looks like a guy named #ctrlplusb ;) made an extension for this: https://github.com/ctrlplusb/gun-most . Nice one!

How does browserify handle circular dependencies?

I'm considering moving a large browser-based code base over to CommonJS (it's an AngularJS 1.x application written in TypeScript). The application has circular dependencies, so I think RequireJS is out of the question.
How does Browserify handle circular dependencies? Are there different categories of circular dependencies that are/aren't supported? Or any tips for working with circular dependencies with CommonJS/Browserify?
Browserify does not add special treatment to cyclic dependencies and the behavior is inherited from Node.
It goes as shown in Node Modules documentation which I'm integrally quoting it below:
When there are circular require() calls, a module might not have finished executing when it is returned.
Consider this situation:
a.js:
console.log('a starting');
exports.done = false;
const b = require('./b.js');
console.log('in a, b.done = %j', b.done);
exports.done = true;
console.log('a done');
b.js:
console.log('b starting');
exports.done = false;
const a = require('./a.js');
console.log('in b, a.done = %j', a.done);
exports.done = true;
console.log('b done');
main.js:
console.log('main starting');
const a = require('./a.js');
const b = require('./b.js');
console.log('in main, a.done = %j, b.done = %j', a.done, b.done);
When main.js loads a.js, then a.js in turn loads b.js. At that point, b.js tries to load a.js. In order to prevent an infinite loop, an unfinished copy of the a.js exports object is returned to the b.js module. b.js then finishes loading, and its exports object is provided to the a.js module.
By the time main.js has loaded both modules, they're both finished. The output of this program would thus be:
$ node main.js
main starting
a starting
b starting
in b, a.done = false
b done
in a, b.done = true
a done
in main, a.done = true, b.done = true
Careful planning is required to allow cyclic module dependencies to work correctly within an application.