Nuxtjs hook system - vue.js

I wrote my own module for my nuxt.js application. Since upgrading to version 1.4.0 this line:
this.nuxt.plugin('close', () => new Promise((resolve) => server.close(resolve)))
generates following warning:
nuxt.plugin('close',..) is deprecated. Use new hooks system.
However, there does not seem to be any documentation on this 'new hooks system'.
Can anybody tell me what I have to change?
Thank you in advance!

The new hooks are invoked with: this.nuxt.hook(NAME, FN).
// this.nuxt.plugin('close', () => {...})
this.nuxt.hook('close', () => {...})

Related

How to properly test if a Toast has been shown in react native using native base?

I am trying to write a test that checks if the screen is showing a Toast with an error message. The test passes, but there is a warning:
console.error
Warning: You called act(async () => ...) without await.
This could lead to unexpected testing behaviour, interleaving multiple act calls
and mixing their scopes. You should - await act(async () => ...);
The screen is working fine, I am just learning how to write tests. This is my test:
it('shows error correctly', async () => {
mockAxios.get.mockRejectedValueOnce(new Error('Async error'))
const { queryByText } = renderWithRedux(<DiscoverScreen />)
await waitFor(() => {
expect(queryByText(ErrorMessages.GeneralErrorToast)).not.toBeNull()
})
await waitForElementToBeRemoved(() => queryByText(ErrorMessages.GeneralErrorToast), { timeout: 5000 })
})
What am I not doing right? Definitely there is an issue with react native testing, because there are problems for certain async querying, especially when you have several of them. I found that here: https://github.com/callstack/react-native-testing-library/issues/379#issuecomment-720734366
I am using native base for showing the Toast, which is using Animated I think. Should I use jest.useFakeTimers() and how?
After researching how the Toast in native base works (this could be done when you open the source code in github - https://github.com/GeekyAnts/NativeBase/blob/master/src/basic/ToastContainer.js), I found that it uses Animated.timing.
So I had to find out how to deal with react native animations in tests. That article had a solution that worked for me: https://medium.com/#joncardasis/react-native-how-to-test-components-implementing-animated-with-jest-8cabb5fc2730
After I added the code in my jest setup file, this is how my test looks:
global.withAnimatedTimeTravelEnabled(async () => {
const { queryByText } = renderedComponent
await waitFor(() => {
expect(queryByText(ErrorMessages.GeneralErrorToast)).not.toBeNull()
})
global.timeTravel(Constants.ErrorToastDelay)
expect(queryByText(ErrorMessages.GeneralErrorToast)).toBeNull()
})
It works and now the test passes with no warnings!
One little adjustment in my jest configuration was also missing. I had to add this:
"testEnvironment": "jsdom"
I hope this could help someone else, too!

Vue dynamic import is being imported even if it is never used

I am building a vue plugin called vue-scan-field. At the previous version (0.1.2) the plugin only supported vuetify. Now I want to also add quasar to this plugin. So what I have decided to do is use dynamic imports for the components. For example the quasar file looks like this:
export default {
components: {
scan_text_field: () => import('quasar/src/components/input/QInput'),
scan_textarea: () => import('quasar/src/components/input/QInput'),
scan_checkbox: () => import('quasar/src/components/checkbox/QCheckbox'),
scan_select: () => import('quasar/src/components/select/QSelect')
},
...
}
And I also have this for vuetify:
export default {
components: {
scan_text_field: () => import('vuetify/lib/components/VTextField'),
scan_textarea: () => import('vuetify/lib/components/VTextarea'),
scan_checkbox: () => import('vuetify/lib/components/VCheckbox/VCheckbox'),
scan_select: () => import('vuetify/lib/components/VAutocomplete'),
},
...
}
Now download the module from npm and run my quasar project I get these errors:
These dependencies were not found:
* vuetify/lib/components in ./node_modules/vue-scan-field/dist/vue-scan-field.esm.js
* vuetify/lib/components/VAutocomplete in ./node_modules/vue-scan-field/dist/vue-scan-field.esm.js
* vuetify/lib/components/VCheckbox/VCheckbox in ./node_modules/vue-scan-field/dist/vue-scan-field.esm.js
* vuetify/lib/components/VTextField in ./node_modules/vue-scan-field/dist/vue-scan-field.esm.js
* vuetify/lib/components/VTextarea in ./node_modules/vue-scan-field/dist/vue-scan-field.esm.js
Now this can be because maybe my compiler imports the components on build. I don't know if I can safely disable this function (I don't think so). Is there any way to fix this?
NPM Package: https://www.npmjs.com/package/vue-scan-field
Github page: https://github.com/jessielaf/vue-scan-field
Dynamic components in Webpack (and in general) work because bundler at build time prepares js files (with component code) which are at runtime loaded (or not ...depending on logic) by the app. Bundler can not execute your code and evaluate the logic which decides which component should be loaded. It must prepare the budle for all possible outcomes.
So yes, of course your bundler looks for and bundle all the files even they are used in dynamic import.
I do not know exactly how to set up Rollup correctly but I'm pretty sure you don't want to include any Vuetify/Quasar code as part of your library. Such code would be duplicate and possibly from different version of the framework the user of your library is already using! So instead of using string configuration (framework: 'vuetify'), leave it to your users to pass the component mapping (and maybe add sample to your docs)...
// dynamic
Vue.use(ScanField, { components: {
scan_text_field: () => import('quasar/src/components/input/QInput'),
scan_textarea: () => import('quasar/src/components/input/QInput'),
scan_checkbox: () => import('quasar/src/components/checkbox/QCheckbox'),
scan_select: () => import('quasar/src/components/select/QSelect'),
scan_date: () => null
}})
// static
import QInput from 'quasar/src/components/input/QInput'
Vue.use(ScanField, { components: {
scan_text_field: QInput,
...
}})
Alternative solution is to use normal (not dynamic) imports, but configure Rollup so that both Vuetify and Quasar are treated as peerDependencies (dependency your lib requires but the user is responsible to add/install it into his project) - see the docs

How to disable React Native YellowBox messages in jest tests

I know how to disable YellowBox warning when running in the device:
YellowBox.ignoreWarnings(ignoredYellowBox);
But I don't know how to silence them in a jest test. There are some deprecation warnings that we cannot deal with atm and they are making our tests very noisy. I'd rather not block every YellowBox warning from our tests, but if necessary, that would work too.
It is a pretty annoying thing. This is what we came up with:
const warnings = [
'Warning: NetInfo has been extracted from react-native core and will be removed in a future release.',
'inside a test was not wrapped in act(...).',
];
const oldError = console.error;
jest.spyOn(console, 'error').mockImplementation((...args) => {
const string = args.join(' ');
if (warnings.some(warning => string.match(warning))) return;
oldError(...args);
});
Add that snippet to your jest setup file, and edit the warnings array as appropriate for your situation.
For future readers, there is a simple way to do this.
jest.spyOn(console, 'warn').mockImplementation(() => {})
jest.spyOn(console, 'error').mockImplementation(() => {})
For TypeScript:
jest.spyOn(console, 'warn').mockImplementation(() => undefined)
jest.spyOn(console, 'error').mockImplementation(() => undefined)
Remember that by using an approach like this you are disabling all console errors and warnings.
If you want to keep other errors and warnings, just use the first answer in this question.

How to call AppRegistry.registerComponent with some delay

I need to read some user settings before App initialize. This settings will update the style of the app.
I called AppRegistry.registerComponent with some delayed but app crashed. Have found this issue on https://github.com/facebook/react-native/issues/17724 but nothing helps.
I found answer
AppRegistry.registerComponent("App", () => App);
AppRegistry.registerRunnable(appName, initParams => {
setTimeout(
() => AppRegistry.runApplication("App", initParams),
5000
);
});

Priority-Web-SDK btoa "Buffer is not defined"

I'm building a React Native application using create-react-native-app. The app connects to Priority via the API without error, however when I need to use the Web-SDK to get the options for a choose field it is throwing an error:
SDK Error: ReferenceError: Buffer is not defined
at btoa (C:\...\node_modules\btoa\index.js:8)
at b64encode (C:\...\node_modules\priority-web-sdk\index.js:2744)
at $FormQuery (C:\...\node_modules\priority-web-sdk\index.js:3898)
at $GetRows (C:\...\node_modules\priority-web-sdk\index.js:3957)
at Form_1.GetRows (C:\...\node_modules\priority-web-sdk\index.js:4673)
at C:\...\node_modules\priority-web-sdk\index.js:6234
at tryCallTwo (C:\...\node_modules\promise\setimmediate\core.js:45)
at doResolve (C:\...\node_modules\promise\setimmediate\core.js:200)
at new Promise (C:\...\node_modules\promise\setimmediate\core.js:66)
at Object.gform.getRows (C:\...\node_modules\priority-web-sdk\index.js:6233)
**Actual files paths edited for brevity/privacy.
My code that calls getRows()
return login(configuration)
.then(() => formStart('PORDERS', null, null, configuration.company, 1))
.then(form => myForm = form)
.then(() => myForm.setSearchFilter(filter))
.then(() => myForm.getRows(1))
.then(r => rows = r)
.then(() => myForm.setActiveRow(1))
.then(a => row = a)
.then(() => myForm.choose('STATDES',rows.PORDERS[row.rowindex].STATDES))
.then((response) => {return response.ChooseLine})
.catch(err => console.log('SDK Error: ', err));
This issue popped up recently. It was working fine before. I thought maybe I had upgraded a package incorrectly, so I reverted to a previous version of the yarn.lock file and rebuilt the node_modules folder, but with no success.
I feel like this is more of a yarn/npm package or Priority issue than React-native, but I'm at a loss. Any suggestions on what else I could do?
Update:
The more I work on this and the more I try different things, it feels to me more and more like an issue of my test setup having different native functions than my live set up. Any suggestions on how to check/solve that?
This is fixed in version 1.9.3 of priority-web-sdk.
In addition, here is a link to Priority Master app's repository that is built with react-native: https://github.com/PrioritySoftware/priority-master-react.