react native reselect error selector creators except all input - react-native

what I do am wrong ?
reselect.js
import { createSelector } from 'reselect';
const createCollection = state => state.createCollection;
export const getCollectionName = createSelector(
createCollection,
(el) => el
);
if I only import the file, then I get this error:
Error: Selector creators expect all input-selectors to be functions, instead received the following types: [undefined]

Must be an import problem, you have no error in the code you provided:
const { createSelector } = Reselect;
const state = {};
const createCollection = state => state.createCollection;
const getCollectionName = createSelector(
createCollection,
(el) => el
);
console.log(getCollectionName(state))
console.log(
'also works:'
,getCollectionName(
{createCollection:'hello world'}
)
)
<script src="https://cdnjs.cloudflare.com/ajax/libs/reselect/4.0.0/reselect.min.js"></script>
You should probably log what createCollection is before using it in createSelector.
You should prefix your selectors with select so your future self and other members of your team can recognise the selectors: selectCreateCollection and selectCollectionName

Related

i18n won't translate correctly when inside array or object in React Native

I'm trying to use i18n-js to translate some strings into other languages. If I have my code in normal code, it works. Ex:
//Displays "Something" (no quotes) where I want it
<Text> translate("Something"); </Text>
But if I put it inside an array or object, then call it later, it stops working and shows a missing message instead of the text I want translated. Ex:
const messages = {
something: translate("Something"),
// other translations...
}
// later on
// Displays "[missing "en.Something" translation]" (no quotes) where I want it
<Text> messages.something </Text>
The following is my code for my translate function, as well as the config for i18n. I'm using lodash-memoize, but that is unrelated to the issue. I've already checked that the text being passed to i18n.t() is the same (including type) no matter if it's in normal code or in the array, but it still doesn't return the correct thing. I have some error checking written up to avoid getting the missing message on screen, but that still doesn't fix the issue that it can't find the translation.
export const translationGetters = ({
en: () => require('./translations/en.json'),
es: () => require('./translations/es.json')
});
export const translate = memoize(
(key, config) => {
text = i18n.t(key, config)
return text
},
(key, config) => (config ? key + JSON.stringify(config) : key)
);
export const setI18nConfig = () => {
// fallback if no available language fits
const fallback = { languageTag: "en", isRTL: false };
const { languageTag, isRTL } =
RNLocalize.findBestAvailableLanguage(Object.keys(translationGetters)) ||
fallback;
// clear translation cache
translate.cache.clear();
// update layout direction
I18nManager.forceRTL(isRTL);
// set i18n-js config
i18n.translations = { [languageTag]: translationGetters[languageTag]() };
i18n.locale = languageTag;
};
I have no idea where to go on this. Any advice would be appreciated!
Same problem here, workaround is to return array/object from inside a function:
Don't work
export const translations = [i18.t('path')]
Works
export function getTranslations() {
const translations = [i18.t('path')]
return translations
}

Test case for child components onClick function

I want to test the onClick functionality of MenuPopover.Item id={3} if it was called once or not after clicking on it.
import React from 'react';
import copy from 'copy-to-clipboard';
const TableMenu = ({show, target, onClick, onHide, addedType, disable, readonly, rowId, supportRestore, supportDelete, isRestored}) => (
<MenuPopover
onClick={onClick}
onHide={onHide}>
{!readonly && (addedType ?
<MenuPopover.Item id={1} label='Delete' disabled=true/> :
<MenuPopover.Item id={2} label='Restore' disabled=false/>
)}
<MenuPopover.Item id={3} onClick={() => copy(rowId)} label='Copy'/>
</MenuPopover>
);
Test case written so far
const onCopySpy = sinon.spy();
const props = {
///
onCopy: onCopySpy,
///
};
it('check method onCopy called', () => {
const wrapper = shallow(<TableMenu {...props}/>);
expect(wrapper.find('MenuPopover').children()).to.have.lengthOf(2);
wrapper.find(MenuPopover.Item).... //Test case to call the onClick function
expect(onCopySpy.calledOnce).to.eql(true);
});
copy needs to be mocked in tests:
import copy from 'copy-to-clipboard';
jest.mock('copy-to-clipboard', () => sinon.spy());
...
const wrapper = shallow(<TableMenu {...props}/>);
wrapper.find(MenuPopover.Item).props().onClick();
expect(copy.calledOnce).to.eql(true);
This can be alternatively done with simulate but it does the same thing internally.

Upgrading from RxJS5 to RxJS6

I'm having an issue upgrading from RxJS5 to version 6. I've got the following code:
private captureEvents(canvasEl: HTMLCanvasElement) {
Observable
.fromEvent(canvasEl, 'mousedown')
.switchMap((e) => {
return Observable
.fromEvent(canvasEl, 'mousemove')
.takeUntil(Observable.fromEvent(canvasEl, 'mouseup'))
.pairwise()
})
.subscribe((res: [MouseEvent, MouseEvent]) => {
const rect = canvasEl.getBoundingClientRect();
const prevPos = {
x: res[0].clientX - rect.left,
y: res[0].clientY - rect.top
};
const currentPos = {
x: res[1].clientX - rect.left,
y: res[1].clientY - rect.top
};
this.drawOnCanvas(prevPos, currentPos);
});
}
But when I upgrade to RxJS6 I get the following error:
Property 'fromEvent' does not exist on type 'typeof Observable'.
I tried to change my imports from this (RxJS5):
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/fromEvent';
import 'rxjs/add/operator/takeUntil';
import 'rxjs/add/operator/pairwise';
import 'rxjs/add/operator/switchMap';
To this (RxJS6):
import { Observable, fromEvent } from 'rxjs';
import { switchMap, takeUntil, pairwise } from 'rxjs/operators';
This was my best attempt up upgrading the code:
private captureEvents(canvasEl: HTMLCanvasElement) {
const obsMouseDown = fromEvent(canvasEl, 'mousedown').pipe(
switchMap((e) => {
const obsMouseMove = fromEvent(canvasEl, 'mousemove').pipe(
takeUntil(a => {
const obsMouseUp = fromEvent(canvasEl, 'mouseup').pipe(
pairwise()
);
return obsMouseUp;
}));
return obsMouseMove;
}))
.subscribe((res: [MouseEvent, MouseEvent]) => {
const rect = canvasEl.getBoundingClientRect();
const prevPos = {
x: res[0].clientX - rect.left,
y: res[0].clientY - rect.top
};
const currentPos = {
x: res[1].clientX - rect.left,
y: res[1].clientY - rect.top
};
this.drawOnCanvas(prevPos, currentPos);
});
}
But this isn't working - I get an error for the "takeUntil" code:
Argument of type '(a: any) => Observable<[Event, Event]>' is not
assignable to parameter of type 'Observable'
plnkr example of original code here:
https://embed.plnkr.co/QSvJxi/
For some reason your plnkr didn't work for me but I'll try my best to provide an answer. I think you should do 2 things here for starter. Try initializing your Observables so it's easier to call them and subscribe to them like so:
const mousedown$ = fromEvent(pauseButton, 'mousedown');
const mouseup$ = fromEvent(resumeButton, 'mouseup');
const mousemove$ = fromEvent(resumeButton, 'mousemove');
The second thing you should pipe your operators now with Rxjs 5 & 6, like so, And subscribe to all your events
mousedown$.pipe(
switchMap(res => {
mousemove$.pipe(//Whatever Operators and subscribitions to other events).subscribe(...)
}),
map(// Whatever you want back from your event)
).subscribe(...)
I refer to you the documentation links switchMap && takeUntil . As many syntaxes are changing in Rxjs don't be shy to brows the documentation, there is nothing better.
fromEvent
Now is already of type Observable. You don't need the chain it to an Observebal instead you can call it directly and affect it to a variable or better a const. Like below:
const source = fromEvent(document, 'click');
as for the import, you figured it right
import { fromEvent } from 'rxjs';
I think you are actually very close, I think you have your pipes too "deep" though - remember you can chain as many operators as you need together in a pipe, so your inner mouse-move-until-mouse-up switchmap should look more like this:
private captureEvents(canvasEl: HTMLCanvasElement) {
const obsMouseDown = fromEvent(canvasEl, 'mousedown').pipe(
switchMap((e) => {
return fromEvent(canvasEl, 'mousemove').pipe(
takeUntil(a => fromEvent(canvasEl, 'mouseup')),
pairwise()
));
}))
.subscribe((res: [MouseEvent, MouseEvent]) => {
// snip
});
}

React-Native - Can't find variable : Proxy

i'm using Proxy for my react native app
import Setting from "./Setting";
const lang = { ar : {...} , en : {...} , fr : {...} };
export const string = new Proxy(lang, {get: function (object, name){return object[Setting.settings.lang][name]}});
export default string;
but throws cannot find variable Proxy
I can't add a comment, but i think your question is linked to the same question:-
Proxy ES6
In otherwords, you'll need to import a polyfill.
--
Edited to add the codes:
import 'proxy-polyfill';
.
.
_samplePolyfill = () => {
function observe(o, callback) {
return new Proxy(o, {
set(target, property, value) {
callback(property, value);
target[property] = value;
},
});
}
const x = {'name': 'BB-8'};
const p = observe(x, (property, value) => console.warn(property, value));
p.name = 'BB-9';
}
.
.
componentDidMount() {
this._samplePolyfill();
}
For a weird reason if you enable RemoteJs Debugger it works
Ctrl/CMD + M
if you had issue connecting to remote debugger follow this :
Unable to connect with remote debugger

Crash with simple history push

just trying come silly stuff and playing around with Cycle.js. and running into problem. Basically I just have a button. When you click it it's suppose to navigate the location to a random hash and display it. Almost like a stupid router w/o predefined routes. Ie. routes are dynamic. Again this isn't anything practical I am just messing with some stuff and trying to learn Cycle.js. But the code below crashes after I click "Add" button. However the location is updated. If I actually just navigate to "#/asdf" it displays the correct content with "Hash: #/asdf". Not sure why the flow is crashing with error:
render-dom.js:242 TypeError: Cannot read property 'subscribe' of undefined(…)
import Rx from 'rx';
import Cycle from '#cycle/core';
import { div, p, button, makeDOMDriver } from '#cycle/dom';
import { createHashHistory } from 'history';
import ranomdstring from 'randomstring';
const history = createHashHistory({ queryKey: false });
function CreateButton({ DOM }) {
const create$ = DOM.select('.create-button').events('click')
.map(() => {
return ranomdstring.generate(10);
}).startWith(null);
const vtree$ = create$.map(rs => rs ?
history.push(`/${rs}`) :
button('.create-button .btn .btn-default', 'Add')
);
return { DOM: vtree$ };
}
function main(sources) {
const hash = location.hash;
const DOM = sources.DOM;
const vtree$ = hash ?
Rx.Observable.of(
div([
p(`Hash: ${hash}`)
])
) :
CreateButton({ DOM }).DOM;
return {
DOM: vtree$
};
}
Cycle.run(main, {
DOM: makeDOMDriver('#main-container')
});
Thank you for the help
I would further suggest using #cycle/history to do your route changing
(Only showing relevant parts)
import {makeHistoryDriver} from '#cycle/history'
import {createHashHistory} from 'history'
function main(sources) {
...
return {history: Rx.Observable.just('/some/route') } // a stream of urls
}
const history = createHashHistory({ queryKey: false })
Cycle.run(main, {
DOM: makeDOMDriver('#main-container'),
history: makeHistoryDriver(history),
})
On your function CreateButton you are mapping your clicks to history.push() instead of mapping it to a vtree which causes the error:
function CreateButton({ DOM }) {
...
const vtree$ = create$.map(rs => rs
? history.push(`/${rs}`) // <-- not a vtree
: button('.create-button .btn .btn-default', 'Add')
);
...
}
Instead you could use the do operator to perform the hashchange:
function CreateButton({ DOM }) {
const create$ =
...
.do(history.push(`/${rs}`)); // <-- here
const vtree$ = Observable.of(
button('.create-button .btn .btn-default', 'Add')
);
...
}
However in functional programming you should not perform side effects on you app logic, every function must remain pure. Instead, all side effects should be handled by drivers. To learn more take a look at the drivers section on Cycle's documentation
To see a working driver jump at the end of the message.
Moreover on your main function you were not using streams to render your vtree. It would have not been reactive to locationHash changes because vtree$ = hash ? ... : ... is only evaluated once on app bootstrapping (when the main function is evaluated and "wires" every streams together).
An improvement will be to declare your main's vtree$ as following while keeping the same logic:
const vtree$ = hash$.map((hash) => hash ? ... : ...)
Here is a complete solution with a small locationHash driver:
import Rx from 'rx';
import Cycle from '#cycle/core';
import { div, p, button, makeDOMDriver } from '#cycle/dom';
import { createHashHistory } from 'history';
import randomstring from 'randomstring';
function makeLocationHashDriver (params) {
const history = createHashHistory(params);
return (routeChange$) => {
routeChange$
.filter(hash => {
const currentHash = location.hash.replace(/^#?\//g, '')
return hash && hash !== currentHash
})
.subscribe(hash => history.push(`/${hash}`));
return Rx.Observable.fromEvent(window, 'hashchange')
.startWith({})
.map(_ => location.hash);
}
}
function CreateButton({ DOM }) {
const create$ = DOM.select('.create-button').events('click')
.map(() => randomstring.generate(10))
.startWith(null);
const vtree$ = Rx.Observable.of(
button('.create-button .btn .btn-default', 'Add')
);
return { DOM: vtree$, routeChange$: create$ };
}
function main({ DOM, hash }) {
const button = CreateButton({ DOM })
const vtree$ = hash.map(hash => hash
? Rx.Observable.of(
div([
p(`Hash: ${hash}`)
])
)
: button.DOM
)
return {
DOM: vtree$,
hash: button.routeChange$
};
}
Cycle.run(main, {
DOM: makeDOMDriver('#main-container'),
hash: makeLocationHashDriver({ queryKey: false })
});
PS: there is a typo in your randomstring function name, I fixed it in my example.