I’m a newbie to React Native and Expo and I want to implement an SQLite database from “/assets/test.db” as you can see on sqlitebrowser:
sqlitebrowser sreenshot
I tried many ways but it never work so I based my code on the most popular way I found : https://forums.expo.io/t/solved-import-asset-db/11469
These things been sayed, here’s my code:
//App.js
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
import * as FileSystem from 'expo-file-system'
import * as SQLite from 'expo-sqlite'
import { Asset } from 'expo-asset'
export default class App extends React.Component {
constructor(props) {
super(props)
this.state = {
item: null
}
}
componentDidMount() {
this.makeSQLiteDirAsync()
FileSystem.downloadAsync(
Asset.fromModule(require("./assets/test.db")).uri,
`${FileSystem.documentDirectory}SQLite/test.db`
)
.then(function(){
const db = SQLite.openDatabase('test.db');
console.log(db);
db.transaction(tx => {
tx.executeSql('SELECT * FROM User;',
[],
(_, {rows}) => console.log(rows))
},
);
});
}
makeSQLiteDirAsync = async() => {
const dbTest = SQLite.openDatabase('dummy.db');
try {
await dbTest.transaction(tx => tx.executeSql(''));
} catch(e) {
if (this.state.debugEnabled) console.log('error while executing SQL in dummy DB');
}
}
render() {
return (
<View style={styles.container}>
<Text>Open up App.js to start working on your app!</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
And here’s the result on terminal:
WebSQLDatabase {
"_currentTask": null,
"_db": SQLiteDatabase {
"_closed": false,
"_name": "test.db",
},
"_running": false,
"_txnQueue": Queue {
"length": 0,
},
"exec": [Function anonymous],
"version": "1.0",
}
Many peoples also advised to change ‘app.json’ and ‘metro.config.js’ the following way:
//app.json
{
"expo": {
"name": "Test: server",
"slug": "snack-42ed5540-be82-47b4-898a-d9acb300c559",
"privacy": "public",
"sdkVersion": "35.0.0",
"platforms": [
"ios",
"android",
"web"
],
"version": "1.0.0",
"orientation": "portrait",
"icon": "./assets/settings.png",
"splash": {
"image": "./assets/settings.png",
"resizeMode": "contain",
"backgroundColor": "#ffffff"
},
"updates": {
"fallbackToCacheTimeout": 0
},
"assetBundlePatterns": [
"**/*"
],
"ios": {
"supportsTablet": true
},
"packagerOpts": {
"assetExts": ["db"]
}
}
}
//metro.config.js
module.exports = {
resolver: {
assetExts: ["db", "mp3", "ttf"]
}
}
I didn’t find anything really different on the other topics or forums so there must be something I did wrong but I don’t see anything I can do to manage it. If you have any question or solution I’ll be there !
The makeSQLiteDirAsync function is to just ensure the SQLite folder is created in the device. Anyway the issue here is that react native will ignore the test.db file when bundling the assets like json, images, etc.
We need to instruct the metro bundler to allow the packaging of the SQLite .db file present in the assets folder. Code should work file if you add your additional assets extensions to the set of default assets already supported.
//metro.config.js
const defaultAssetExts = require("metro-config/src/defaults/defaults").assetExts;
module.exports = {
resolver: {
assetExts: [
...defaultAssetExts,
"db",
"sqlite"
]
}
};
You can check metro-config folder in node_modules and also check the file in node_modules/metro-config/src/defaults/defaults.js to see the list of default assets.
Also, another thing to note is that expo does not recognize below option in app.json. Best to remove this.
"packagerOpts": {
"assetExts": ["db"]
}
Related
I have used wagmi for wallet connect and using next js , the wallet trigger and open extension of coinbase in local but when we deploy it on sever it always tell to install even though it is already installed. I am sharing my connection tried using both alchemy and infura provider but not working . Any idea anybody.shared pic the wallet is installed but still it ask to install
import {
configureChains,
createClient,
goerli,
mainnet,
WagmiConfig,
} from "wagmi";
import { alchemyProvider } from "wagmi/providers/alchemy";
import { infuraProvider } from "wagmi/providers/infura";
import { publicProvider } from "wagmi/providers/public";
import { ReactNode } from "react";
import { CoinbaseWalletConnector } from "wagmi/connectors/coinbaseWallet";
import { MetaMaskConnector } from "wagmi/connectors/metaMask";
import { WalletConnectConnector } from "wagmi/connectors/walletConnect";
interface WalletProviderInterface {
children: ReactNode;
}
const WalletProvider = ({ children }: WalletProviderInterface) => {
const { chains, provider, webSocketProvider } = configureChains(
[mainnet],
[
alchemyProvider({
apiKey: process.env.NEXT_PUBLIC_ALCHEMY_KEY || "",
}),
infuraProvider({ apiKey: process.env.NEXT_PUBLIC_INFURA_KEY || "" }),
]
);
const connectors = [
new MetaMaskConnector({
chains,
options: {
shimDisconnect: true,
shimChainChangedDisconnect: false,
},
}),
new CoinbaseWalletConnector({
chains,
options: {
appName: `test app`,
jsonRpcUrl: `https://ethmainnet.g.alchemy.com/v2/${process.env.NEXT_PUBLIC_ALCHEMY_KEY}`,
},
}),
new WalletConnectConnector({
chains,
options: {
// alchemyId:process.env.NEXT_PUBLIC_ALCHEMY_KEY,
qrcode: true,
},
}),
];
const client = createClient({
autoConnect: true,
connectors,
provider,
webSocketProvider,
});
return <WagmiConfig client={client}>{children}</WagmiConfig>;
};
export default WalletProvider;
I am working on a project which is set up with lerna mono repo, we have multiple stencilJS projects for an individual component inside packages of monorepo.
My project sructure is:
I am new to the storybook, now I have to set up the storybook at the root level which all the packages storybook.
I followed an article on the internet and I have set up something which works only for a single package component, due to the current style of setup.
Due to defineCUstomElements in preview.js it is loading the first project package loader I am able to see only the first project stories. Css is not loading for second project stories.
Can someone help me to set up a storybook at the root level which works for all packages?
My example
storybook/main.js
module.exports = {
"stories": [
"../stories/**/*.stories.mdx",
"../packages/plugin-*/src/components/plugin-*/*.stories.#(js|jsx|ts|tsx)"
],
"addons": [
'#storybook/addon-links',
'#storybook/addon-essentials',
'#storybook/addon-viewport',
'#storybook/addon-notes',
'#storybook/addon-docs'
]
}
storybook/preview.js
import { defineCustomElements } from '../packages/stencilProj1/loader';;
defineCustomElements();
export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
};
package/stencilProj1/component1.stories.ts
import readme from './readme.md'
import React from 'react';
import ComponentButton from '../../../dist/collection/components/ComponentButton /ComponentButton';
export default {
title: 'Button',
component: ComponentButton,
argTypes: {
label: { control: 'text' },
type: { type: 'select', options: ['primary'] },
disabled: { control: 'boolean' }
},
parameters: {
markdown: readme
},
};
const Template = ({ label, type, disabled = false }) => {
return <component-button type={type} disabled={disabled}>{label}</component-button>;
};
export const Primary = Template.bind({});
Primary.args = {
type: 'primary',
label: 'Primary Button',
};
After a couple of months of attempts, I finally solved this puzzle :) And want to share my solution with community
I have a lerna v4 monorepo for react v17 + mui v5 components written in typescript and flavored with storybook v6 and webpack v5
mui has its wrappers in preview.js, that's why I added the path to .storybook in babel-loader
module.exports = {
core: {
builder: "webpack5",
},
framework: "#storybook/react",
stories: ["../components/**/*.stories.#(ts|tsx)"],
addons: [
"#storybook/addon-links",
"#storybook/addon-essentials",
{
name: "#storybook/preset-create-react-app",
options: {
craOverrides: {
fileLoaderExcludes: ["less"],
},
},
},
],
webpackFinal: config => {
const {
module: {
rules: [, , , , , { oneOf }],
},
} = config;
const babelLoader = oneOf.find(({ test }) => new RegExp(test).test(".ts"));
babelLoader.include = [/components\/(.*)\/src/, /.storybook/];
babelLoader.options.sourceType = "unambiguous";
return config;
},
};
it is also worth to mention my tsconfig has these lines
"rootDirs": [
"./src",
],
Have you tried to import project 2's defineCustomElement with "as" to rename it and use it?
(something along the line of following inside preview.js)
import { defineCustomElements } from '../packages/stencilProj1/loader';
import { defineCustomElements as defineSecondProject } from '../packages/stencilProj2/loader';
defineCustomElements();
defineSecondProject();
This is very manual and even if this works, if you have many repo might not be good solution but I've done something similar to load multiple component loaders and that seem to work OK for my use case in the past.
I'd like to build a Nuxt.js App, in this case, I'm using dynamic routes that to be generated by using config.
Well, I got an issue when I was trying to generate my web page using Nuxt & Firebase.
Here are my Nuxt Config JS code :
import * as firebase from 'firebase';
import 'firebase/auth';
import 'firebase/database';
var firebaseConfig = {
apiKey: "AIzaSyAOX6yNHPzWHWd30GnDagwlhgGv9iP8kLs",
authDomain: "musthofa-lapor.firebaseapp.com",
databaseURL: "https://musthofa-lapor.firebaseio.com",
projectId: "musthofa-lapor",
storageBucket: "musthofa-lapor.appspot.com",
messagingSenderId: "653288691711",
appId: "1:653288691711:web:e49daf72720bf99dc5f9ca",
measurementId: "G-0KW7CGZHL3"
};
var app = firebase.initializeApp(firebaseConfig);
var dbx = app.database();
export default {
mode: 'universal',
/*
** Headers of the page
*/
head: {
title: process.env.npm_package_name || '',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: process.env.npm_package_description || '' }
],
link: [
{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
],
script:[
{ src:'https://www.gstatic.com/firebasejs/7.2.3/firebase-app.js' },
{ src:'https://www.gstatic.com/firebasejs/7.2.3/firebase-auth.js' },
{ src:'https://www.gstatic.com/firebasejs/7.2.3/firebase-database.js' },
{ src:'https://www.gstatic.com/firebasejs/7.2.3/firebase-storage.js' },
]
},
/*
** Customize the progress-bar color
*/
loading: { color: '#fff' },
/*
** Global CSS
*/
css: [
],
/*
** Plugins to load before mounting the App
*/
plugins: [
],
/*
** Nuxt.js dev-modules
*/
buildModules: [
],
/*
** Nuxt.js modules
*/
modules: [
],
/*
** Build configuration
*/
build: {
/*
** You can extend webpack config here
*/
extend (config, { isDev, isClient }) {
if (isDev && isClient) {
config.module.rules.push({
enforce: 'pre',
test: /\.(js|vue)$/,
loader: 'eslint-loader',
exclude: /(node_modules)/
})
}
}
},
generate:{
routes(){
return dbx.ref('aspirasi').once("value",function(snap){
snap.forEach(function(snapshot){
var this_val = snapshot.val();
return {
route: '/admin/balas/' + this_val.id
}
})
})
}
}
}
It generated error as follows :
ERROR undefined 06:38:45
TypeError: Cannot read property '_normalized' of undefined
at normalizeLocation (/Volumes/DAKSA-HDD/PROJECTS/PRANANDA/MUSTHOFA LAPOR RAKYAT/PROJECTS/WEBSITE/MAIN/musthofa-web/node_modules/vue-router/dist/vue-router.common.js:1297:12)
at VueRouter.resolve (/Volumes/DAKSA-HDD/PROJECTS/PRANANDA/MUSTHOFA LAPOR RAKYAT/PROJECTS/WEBSITE/MAIN/musthofa-web/node_modules/vue-router/dist/vue-router.common.js:2627:18)
at st (server.js:1:31205)
at async e.default (server.js:1:32623)
Any helps will be appreciated. Thank you so much.
Best Regards
This is caused by returning null or undefined from the routes method, and indeed that is what's happening. There's 2 issues with your code:
You are not returning a value from your callback function.
Using return in a forEach does not return the value to the caller. forEach has a return type of undefined, so you should use map instead.
routes(){
return dbx.ref('aspirasi').once("value",function(snap){
return snap.map(function(snapshot){
var this_val = snapshot.val();
return {
route: '/admin/balas/' + this_val.id
}
})
})
}
Bonus: Your code could be cleaned up a lot by using ES6 syntax and async/await:
async routes() {
const snapshot = await dbx.ref("aspirasi").once("value")
return snapshot.map(snap => ({ route: "/admin/balas/" + snap.val().id }))
}
I have a component:
import React from 'react';
import * as styles from './RedComponent.css';
class RedComponent extends React.Component {
render () {
return <div className={ styles.red }></div>;
}
}
This is the test case:
describe('Test suite', () => {
test('RedComponent tests', () => {
const wrapper = shallow(<RedComponent />);
});
console.log(wrapper.debug());
gives
<div className={[undefined]}></div>
instead of
<div className="RedComponent__red"></div>
If I console the imported styles I get
console.log(styles); // {default: {}}
This is only in Jest test cases. Style is not undefined when the app renders in browser.
My jest config:
{
"moduleFileExtensions": [
"js"
],
"moduleDirectories": [
"node_modules"
],
"moduleNameMapper": {
"\\.(css|less)$": "identity-obj-proxy"
},
"setupFiles": [
"./test-setup.js"
],
"collectCoverageFrom": [
"src/**/*.{js}",
"!**/node_modules/**"
],
"testEnvironment": "node",
"transform": {
"^.+\\.js$": "babel-jest",
"\\.(md|ttf|txt|eot|ico|otf|svg|png|gif|woff2|woff|jpeg)$": "./file-transformer.js"
}
}
Using jest v21.2.1, identity-obj-proxy v3.0.0 and React v16.0.0.
You have to change this line
import * as styles from './RedComponent.css';
to this:
import styles from './RedComponent.css';
I assume that you are using css-loader or similar and this is just how the loader works.
Maybe worths to check the example:
https://github.com/keyanzhang/jest-css-modules-example/
I think your moduleNameMapper should be like this:
"^.+\\.(css|less)$": "identity-obj-proxy"
Create a jest/identity-obj-proxy-esm.js file with the following content:
// This works around the fact we use ES named exports for styles, e.g.:
// import * as styles from './styles.scss'.
// https://github.com/keyanzhang/identity-obj-proxy/issues/8
module.exports = new Proxy(
{},
{
get: function getter(target, key) {
if (key === '__esModule') {
// True instead of false to pretend we're an ES module.
return true;
}
return key;
},
},
);
Edit jest.config.js:
// jest.config.js
module.exports = {
...
moduleNameMapper: {
...
'\\.(css|scss)$': '<rootDir>/jest/identity-obj-proxy-esm.js',
}
};
🏆 João Vieira and https://github.com/keyz/identity-obj-proxy/issues/8#issuecomment-430241345
I'd like to implement the integration testing of my Relay containers against a running GraphQL backend server. I'm going to use Jest for this. I'd like to say that unit testing of React components works well as expected with my Jest setup.
Here's what I have in the package.json for the Jest:
"jest": {
"moduleFileExtensions": [
"js",
"jsx"
],
"moduleDirectories": [
"node_modules",
"src"
],
"moduleNameMapper": {
"^.+\\.(css|less)$": "<rootDir>/src/styleMock.js",
"^.+\\.(gif|ttf|eot|svg|png)$": "<rootDir>/src/fileMock.js"
},
"unmockedModulePathPatterns": [
"<rootDir>/node_modules/react/",
"<rootDir>/node_modules/react-dom/",
"<rootDir>/node_modules/react-addons-test-utils/",
"<rootDir>/node_modules/react-relay/"
]
}
Here's the .babelrc I'm using:
{
"presets": ["es2015", "react", "stage-0"],
"plugins": ["./babelRelayPlugin.js"]
}
Here's the test itself. It must make a request to `http://localhost:10000/q' GraphQL endpoint to fetch a simple piece that represents the info about the current user ('me').
jest.disableAutomock();
import React from 'react';
import Relay from 'react-relay';
import TestUtils from 'react-addons-test-utils';
import RelayNetworkDebug from 'react-relay/lib/RelayNetworkDebug';
RelayNetworkDebug.init();
Relay.injectNetworkLayer(
new Relay.DefaultNetworkLayer('http://localhost:10000/q')
);
describe('Me', () => {
it('can make request to /q anyway', () => {
class RootRoute extends Relay.Route {
static queries = {
root: (Component) => Relay.QL`
query {
root {
${Component.getFragment('root')}
}
}
`,
};
static routeName = 'RootRoute';
}
class AppRoot extends React.Component {
static propTypes = {
root: React.PropTypes.object,
};
render() {
expect(this.props.root).not.toBe(null);
expect(this.props.root.me).not.toBe(null);
expect(this.props.root.me.firstName).not.toBe(null);
expect(this.props.root.me.authorities[0]).not.toBe(null);
expect(this.props.root.me.authorities[0].authority).toEqual('ROLE_ANONYMOUS_AAA');
return (
<div>
{this.props.root.me.firstName}
</div>
);
}
}
const AppContainer = Relay.createContainer(AppRoot, {
fragments: {
root: () => Relay.QL`
fragment on Root {
me {
firstName
email
authorities {
authority
}
}
}
`,
},
});
const container = TestUtils.renderIntoDocument(
<div>
<Relay.RootContainer Component={AppContainer} route={new RootRoute()} />
</div>
);
expect(container).not.toBe(null);
});
});
The problem is that the test passes. But in my opinion it must fail at this line inside the render() expect(this.props.root.me.authorities[0].authority).toEqual('ROLE_ANONYMOUS_AAA');. It seems like the render() method is not executed at all.
I'm running Jest like this
./node_modules/.bin/jest
Does this all suppose to work at all?
Thank you.
This is possible, take a look on the code: https://github.com/sibelius/relay-integration-test
and on my blog post: https://medium.com/entria/relay-integration-test-with-jest-71236fb36d44#.ghhvvbbvl
The missing piece is that you need to polyfill XMLHttpRequest to make it work with React Native.
And you need to polyfill fetch for React web