Unable to get Network IP Address in React Native - react-native

So, I need to get the User's network IPV4 Address. This is my following code and the attempted Libraries that I used for fetching the IPV4 Address. None of them are working.
import React, { useState } from 'react'
import { Text, View, Button } from 'react-native'
import axios from 'axios';
import * as Network from 'expo-network';
import NetInfo from "#react-native-community/netinfo";
import { NetworkInfo } from "react-native-network-info";
import DeviceInfo from 'react-native-device-info';
import publicIP from 'react-native-public-ip';
const App = () => {
const [ipAddress, setIPAddress] = useState('');
//react-native-network-info
NetworkInfo.getIPV4Address().then(ipv4Address => {
console.log(ipv4Address);
setIPAddress(ipv4Address);
});
//react-native-device-info
const getIpAddress = async () => {
const ip = await DeviceInfo.getIpAddress();
console.log(ip);
setIPAddress(ip);
};
//react-native-public-ip
publicIP()
.then(ip => {
console.log(ip);
setIPAddress(ip);
});
//#react-native-community/netinfo
NetInfo.fetch().then(state => {
console.log("Connection type", state.type);
console.log("Is connected?", state.isConnected);
});
//axios
const getData = async () => {
const res = await axios.get('https://geolocation-db.com/json/')
console.log(res.data);
setIPAddress(res.data.IPv4)
};
//expo-network
const ipAlert = async () => {
const ip = await Network.getIpAddressAsync()
setIPAddress(ip);
};
return (
<View style={{ top: 200 }}>
<Text style={{ textAlign: 'center', fontSize: 20 }}>{ipAddress}</Text>
<Button title='GET IP' onPress={getIpAddress} />
</View>
)
};
export default App;
As you can see my code I have tried all the possibilities.
When I run the code, I either get the Public IP Address or an error
ERROR Invariant Violation: Failed to call into JavaScript module method AppRegistry.runApplication(). Module has not been registered as callable. Registered callable JavaScript modules (n = 11): Systrace, JSTimers, HeapCapture, SamplingProfiler, RCTLog, RCTDeviceEventEmitter, RCTNativeAppEventEmitter, GlobalPerformanceLogger, JSDevSupportModule, HMRClient, RCTEventEmitter.
A frequent cause of the error is that the application entry file path is incorrect. This can also happen when the JS bundle is corrupt or there is an early initialization error when loading React Native.
Any Help is Appreciated.
:)
FYI- I tried each one separately, not all together.

i fond there is AppRegistry issue from your given error.
so you have to check root index.js file. and check the imported path of App.js which is highlighted in below example and replace actual path of app.js.
example:
index.js
import {AppRegistry} from 'react-native';
import App from './App'
import App from './App'; check this path
import {name as appName} from './app.json';
AppRegistry.registerComponent(appName, () => App);
/
App.js
import { StyleSheet, Text, View } from 'react-native'
import React, { useState } from 'react'
import publicIP from 'react-native-public-ip';
export default App = () => {
useState(() => {
publicIP()
.then(ip => {
console.log(ip);
// '47.122.71.234'
})
.catch(error => {
console.log(error);
// 'Unable to get IP address.'
});
}, [])
return (
<View>
<Text>App</Text>
</View>
)
}
const styles = StyleSheet.create({})
package is working in my code.

Related

WatermelonDB function hasUnsyncedChanges

I am using WatermelonDB in my RN app. I am trying to display a button if WatermelonDB has unsynced changes. WatermelonDB has a function called hasUnsyncedChanges that returns a boolean. I can get the function to console.log true/false. But unsure how to use this outside of the async function.
async function checkUnsyncedChanges() {
return await hasUnsyncedChanges({database});
}
(async () => {
console.log(await checkUnsyncedChanges());})();
I am new to React Native and have had good luck researching other issues with WatermelonDB but running into a wall in how to get this working.
I figured it out. Code below for anyone having similar difficulties.
import React, {useState, useEffect, useContext} from 'react';
import {View, Text, Button} from 'react-native';
import {hasUnsyncedChanges} from '#nozbe/watermelondb/sync';
import {database} from '../database/db';
import {sync} from '../components/watermelonSync';
import {AuthContext} from '../AuthProvider';
const SyncButton = () => {
const {user} = useContext(AuthContext);
const [showButton, setShowButton] = useState(false);
useEffect(() => {
const checkUnsyncedChanges = async () => {
const unsyncedChanges = await hasUnsyncedChanges({database});
setShowButton(unsyncedChanges);
};
checkUnsyncedChanges();
}, []);
return (
<View>
{showButton && (
<Button title="Sync Changes" onPress={() => sync(user.token)} />
)}
</View>
);
};
export default SyncButton;

undefined is not an object _react.PropTypes.array

I am using React Native (Expo CLI). Since i reinstalled npm i have this error when i try to run npm start I found some similar erros related to react-native-snap-carousel (i am using it).
TypeError: undefined is not an object (evaluating '_react.PropTypes.array')
at node_modules\expo\build\environment\react-native-logs.fx.js:27:4 in error
at node_modules\react-native\Libraries\Core\ExceptionsManager.js:95:4 in reportException
at node_modules\react-native\Libraries\Core\ExceptionsManager.js:141:19 in handleException
at node_modules\react-native\Libraries\Core\setUpErrorHandling.js:24:6 in handleError
at node_modules\#react-native\polyfills\error-guard.js:49:36 in ErrorUtils.reportFatalError
at node_modules\metro-runtime\src\polyfills\require.js:203:6 in guardedLoadModule
at http://192.168.1.6:19000/node_modules%5Cexpo%5CAppEntry.bundle?platform=android&dev=true&hot=false&strict=false&minify=false:202384:3 in global code
So, inside it's main file is imported {PropTypes} from "react"; and changed to import PropTypes from "prop-types"; (previously installed). Also changed propTypes.items: PopTypes.array.isRequired to propTypes.items:PropTypes.array, same to slideStyle (because I started getting new errors related to items and slideStyle are required) but now i am receiving new errors like this.
All errors are related to react-native-snap-carousel
Here is my package.json
Here is how i use react-native-snap-carousel
import React, { useState, useEffect } from "react";
import {
View,
StyleSheet,
Image,
Dimensions,
TouchableWithoutFeedback,
} from "react-native";
import { getBannersApi } from "../../Api/HomeBanner";
import Carousel, { Pagination } from "react-native-snap-carousel";
import { size } from "lodash";
import { useNavigation } from "#react-navigation/native";
import { SERVER_RESOURCERS } from "../../Utils/Constans";
const width = Dimensions.get("window").width;
const height = 160;
export default function Banner() {
const [banners, setBanners] = useState(null);
const [banneActive, setBanneActive] = useState(0);
const navigation = useNavigation();
useEffect(() => {
(async () => {
const response = await getBannersApi();
setBanners(response.data);
})();
}, []);
const goToProduct = (id) => {
navigation.push("product", { idProduct: id });
};
if (!banners) return null;
const renderItem = ({ item }) => {
return (
<TouchableWithoutFeedback
onPress={() => goToProduct(item.attributes.product.data.id)}
>
<Image
style={styles.carousel}
source={{
uri: `${SERVER_RESOURCERS}${item.attributes.banner.data[0].attributes.formats.small.url}`,
}}
/>
</TouchableWithoutFeedback>
);
};
return (
<View style={styles.container}>
<Carousel
layout="default"
data={banners}
sliderWidth={width}
itemWidth={width}
renderItem={renderItem}
loop={true}
onSnapToItem={(i) => setBanneActive(i)}
autoplay={true}
autoplayInterval={5000}
autoplayDelay={2000}
/>
<Pagination
dotsLength={size(banners)}
activeDotIndex={banneActive}
inactiveDotOpacity={0.6}
inactiveDotScale={0.6}
containerStyle={styles.dotsContainer}
dotStyle={styles.dot}
dotColor={styles.dot.backgroundColor}
inactiveDotColor={styles.dot.backgroundColor}
/>
</View>
);
}
I noticed react-native-snap-carousel is not supported anymore so I migrated to react-native-reanimated-carousel

React Native Expo fonts, They are loaded but I can't see the change in my application interface

I am new to using react native. I am using the code contributed in other topics similar to this one:
I use a hook:
import * as Font from "expo-font";
export default useFonts = async () =>
await Font.loadAsync({
Bebas: require('../assets/fonts/BebasNeue-Regular.ttf'),
Montserrat: require('../assets/fonts/Montserrat-Italic-VariableFont_wght.ttf'),
Inter: require('../assets/fonts/Inter-Black.otf')
});
And then in my app.js:
import * as Font from 'expo-font';
import AppLoading from 'expo-app-loading';
import React, { useState } from 'react';
import useFonts from './hooks/useFonts';
export default function App() {
const [IsReady, SetIsReady] = useState(false);
const LoadFonts = async () => {
await useFonts();
};
if (!IsReady) {
return (
<AppLoading
startAsync={LoadFonts}
onFinish={() => SetIsReady(true)}
onError={() => {}}
/>
);
}
return <View styles={styles.container}>{/* Code Here */}</View>;
}
I then try to use them with the same name in my different screens, and I think they are loaded correctly, (no error), but I can't see the change when I restart my application.

Making get request to fetch list list of books from google books api

Search file
as you can see i am making get request to google api, but before rendering this search page it already gives me an error undefined is not an object (evaluating 'items.volumeInfo'), as if i remove this {result === undefined ? null : } line and try to run code it give me perfect title of first book in array(as in search() console.log is working perfectly) after making proper search
import React, {useState, useEffect} from 'react';
import { View, Text } from 'react-native';
import SearchBar from '../components/SearchBar';
import axios from 'axios';
import RenderList from '../components/RenderList';
function SearchScreen() {
const [term, setTerm] = useState("");
const [result, setResult] = useState([]);
const [errorMessage, setErrormessage] = useState("")
const search = async () => {
const res = await axios.get(`https://www.googleapis.com/books/v1/volumes?q=${term}:keyes&key=AIzaSyDfYS8u4y8OADwoUIkl0gYOl0SJQ4GLuaA`, {
headers: {
Accept: "application/json",
"Content-Type": "application-json"
}
})
setResult(res.data.items)
console.log(res.data.items[0].volumeInfo.title)
}
return (
<View>
<SearchBar
term={term}
onTermChange={newTerm => setTerm(newTerm)}
onTermSubmit={() => search()}
/>
{result === undefined ? null : <RenderList result={result} />}
</View>
)
}
export default SearchScreen;
Render file
import React from 'react';
import { View, Text, StyleSheet, FlatList } from 'react-native';
function RenderList({result}) {
return (
<FlatList
data='result'
renderItem={({items}) => {
return <Text>{items.volumeInfo.title}</Text>
}} />
)
}
export default RenderList
Try calling the API in useEffect()
useEffect((
apiCall();)=>{},[searchedText])
Can you please show the Code of SearchBar?

Can't get Jest expo app to work with react-navigation

I am trying to snapshot test with Jest, Expo, React Navigation and my whole app uses hooks only. I'd like to eventually make these into e2e tests where Jest clicks through and snapshot tests everything but I can't even get react navigation to render. My snapshot after the expo loader always shows "null." I followed the basic example from the tabs starter that comes with expo init but the way it outlines how to setup the mocks simply doesn't work for my app. I've tried all sorts of things but nothing works.
App.tsx
import { Ionicons } from '#expo/vector-icons';
import { AppLoading } from 'expo';
import { Asset } from 'expo-asset';
import * as Font from 'expo-font';
import React, { useState } from 'react';
import { YellowBox } from 'react-native';
import { Provider as PaperProvider } from 'react-native-paper';
import { useScreens } from 'react-native-screens';
import { Provider as RxProvider } from 'reactive-react-redux';
import { applyMiddleware, compose, createStore } from 'redux';
import thunk from 'redux-thunk';
import SnackBar from './components/UI/Snackbar';
import { socketMiddleware } from './lib/socketMiddleware';
import SwitchNavigator from './navigation/AppNavigator';
import rootReducer from './reducers/rootReducer';
import { theme } from './Theme';
const middleware = [thunk, socketMiddleware()];
const composeEnhancers = (window as any).__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
export const store = createStore<iAppState, any, any, any>(
rootReducer,
composeEnhancers(applyMiddleware(...middleware))
);
// Must be called prior to navigation stack rendering
useScreens();
YellowBox.ignoreWarnings(['Require cycle:']);
const App = (props) => {
const [isLoadingComplete, setLoadingComplete] = useState(false);
if (!isLoadingComplete && !props.skipLoadingScreen) {
return (
<AppLoading
startAsync={loadResourcesAsync}
onError={handleLoadingError}
onFinish={() => handleFinishLoading(setLoadingComplete)}
/>
);
} else {
return (
<RxProvider store={store}>
<PaperProvider theme={theme}>
<SwitchNavigator />
<SnackBar />
</PaperProvider>
</RxProvider>
);
}
};
const loadResourcesAsync = async () => {
await Promise.all([
Asset.loadAsync([
//nothing
]),
Font.loadAsync({
...Ionicons.font,
TitilliumText250: require('./assets/fonts/TitilliumText22L-250wt.otf'),
TitilliumText800: require('./assets/fonts/TitilliumText22L-800wt.otf')
})
]);
};
const handleLoadingError = (error: Error) => {
console.warn(error);
};
const handleFinishLoading = (setLoadingComplete) => {
setLoadingComplete(true);
};
export default App;
App.test.tsx:
import React from 'react';
import { Provider as PaperProvider } from 'react-native-paper';
import NavigationTestUtils from 'react-navigation/NavigationTestUtils';
import renderer from 'react-test-renderer';
import App from './App';
import { theme } from './Theme';
jest.mock('expo', () => ({
AppLoading: 'AppLoading'
}));
jest.mock('react-native-screens');
jest.mock('react-native-paper');
jest.mock('redux');
jest.mock('reactive-react-redux');
jest.mock('./navigation/AppNavigator', () => 'SwitchNavigator');
describe('App', () => {
jest.useFakeTimers();
beforeEach(() => {
NavigationTestUtils.resetInternalState();
});
// success
it(`renders the loading screen`, () => {
const tree = renderer.create(<App />).toJSON();
expect(tree).toMatchSnapshot();
});
// this snapshot is always null
it(`renders the root without loading screen`, () => {
const tree = renderer
.create(
<PaperProvider theme={theme}>
<App skipLoadingScreen></App>
</PaperProvider>
)
.toJSON();
expect(tree).toMatchSnapshot();
});
});
/navigation/AppNavigator.tsx:
import { createAppContainer, createSwitchNavigator } from 'react-navigation';
import LoginStack from './LoginStack';
import TabStack from './TabStack';
/** The most root navigator which allocates to the others. */
const SwitchNavigator = createAppContainer(
createSwitchNavigator(
{
LoginStack: LoginStack,
TabStack: TabStack
},
{
initialRouteName: 'LoginStack'
}
)
);
export default SwitchNavigator;
I was having a similar issue and found a fix via: https://github.com/expo/expo/issues/7155#issuecomment-592681861
Seems like the act() worked magically for me to stop it from returning null (not sure how)
Update your test to use it like this:
import { act, create } from 'react-test-renderer';
it('renders the root without loading screen', () => {
let tree;
act(() => {
tree = create(
<PaperProvider theme={theme}>
<App skipLoadingScreen></App>
</PaperProvider>
);
});
expect(tree.toJSON()).toMatchSnapshot();
});
Note: When I changed how I was using the imports from 'react-test-renderer' my tests couldn't find act() as a function, a simple re-install of npm packages solved this problem!