I am trying to execute update query but in response getting nothing.
const editData = async (no) => {
try {
db.transaction((tx) => {
tx.executeSql(
'UPDATE brief_History set para' +
no +
'=?,where id=?',
[value, 2],
(tx, results) => {
console.log('Results', results.rowsAffected);
if (results.rowsAffected > 0) {
Alert.alert('Record Updated Successfully...');
} else Alert.alert('Error');
},
);
});
} catch (err) {
console.log(err);
}
};
I was having the same problem, you need to verify if the Database was initialized in App.
Example using Expo
import React, { useEffect, useState } from 'react';
import AppLoading from 'expo-app-loading';
const App = () => {
const [InitializedDatabase, setInitializedDatabase] = useState(false);
useEffect(() => {
let tableValues = { table: "User", column: "Username TEXT, Password TEXT" };
createTable(tableValues).finally(() => setInitializedDatabase(true));
}, []);
if (!InitializedDatabase) {
return <AppLoading />;
}
return (
<View />
);
}
const createTable = (value) =>
new Promise((resolve, reject) =>
db.transaction((tx) =>
tx.executeSql(`CREATE TABLE IF NOT EXISTS ${value.table} (${value.column});`,
[],
(_, { rowsAffected, insertId }) => resolve(insertId),
(_, error) => reject(error)
)));
Related
I need help with the async nature of Async storage and axios api. Here's the functionality that I am trying to achieve ->
send request to two separate api to get some data.
display that data on the screen with some additional text
api request are authenticated so a token is passed as Authentication Header
I have attached the current implementation, I am having the a number of errors in this
Errors:
Login_token not set in state after fetching from Async Storage.
Data not set in state after api call
both resulting in either failed api calls or undefined state errors on render
This is my code.
import React, { FunctionComponent, useEffect, useCallback, useState} from 'react';
import { StyleSheet, View} from 'react-native';
// chat
import { GiftedChat } from 'react-native-gifted-chat';
// navigation
import { RootStackParamList } from '../../navigators/RootStack';
import { StackScreenProps } from '#react-navigation/stack';
export type Props = StackScreenProps<RootStackParamList, "Chat">;
// api
import { Convo_details, Send_Msg, List_Msg, Expert_Public_Profile } from '../../api/UserApi';
import Spinner from 'react-native-loading-spinner-overlay';
import AsyncStorage from '#react-native-async-storage/async-storage';
import uuid from 'react-native-uuid';
const Chat: FunctionComponent<Props> = ({ navigation, route, ...props }) => {
// console.log(props.route.params);
const [login_token, setlogin_token] = useState('')
const [conversation_id, setconversation_id] = useState('')
const [conversation_details, setconversation_details] = useState({})
const [currentuser, setcurrentuser] = useState({})
const [loading, setLoading] = useState(false);
const [expertuid, setexpertuid] = useState('')
const [ExpertProfile, setExpertProfile] = useState({})
const [messages, setMessages] = useState([]);
useEffect(() => {
getlogintoken()
console.log("####################################","getlogintoken");
}, [])
/* conversationid */
useEffect(() => {
if (route.params != null) {
setconversation_id(route.params[0])
}
console.log("####################################","conversation id");
}, [])
/* expert uid */
useEffect(() => {
if (route.params != null) {
setexpertuid(route.params[1])
}
console.log("####################################","expert uid");
}, [])
/* expert public profile */
useEffect(() => {
getexpertpublicprofile()
getConvo_details()
console.log("####################################","convo_details");
}, [])
useEffect(() => {
// get current user
AsyncStorage.getItem("currentuser").then(res => {
if (res != null) setcurrentuser(res)
else alert("Current user not found")
})
console.log("####################################","current user");
}, [])
// set welcome msg
useEffect(() => {
if (Object.keys(conversation_details).length != 0 && Object.keys(ExpertProfile).length != 0)
setwelcomemsg()
}, [])
const onSend = useCallback(async (messages = []) => {
// console.log(messages[0].text);
setMessages(previousMessages => GiftedChat.append(previousMessages, messages))
const data = {
conversation_id: "f98d6851-a713-4f58-9118-77a779ff175f",//conversation_id,
message_type: "TEXT",
body: messages[0].text
}
const res: any = await Send_Msg(data, login_token)
.catch(error => {
alert(`Send_Msg -> ${error}`)
console.log(error);
return
})
if (res.status == 200) {
console.log(res.data);
} else console.log(res);
}, [])
const getexpertpublicprofile = async () => {
setLoading(true)
const res: any = await Expert_Public_Profile(expertuid, login_token)
.catch(error => {
setLoading(false)
console.log("Expert public profile ->");
alert(`Expert public profile ->${error.message}`)
console.log(error);
return
})
setLoading(false)
if (res.status === 200) setExpertProfile(res.data)
else {
alert(`get expert public profile${res.data.message}`)
console.log("getexpertpublicprofile -->");
console.log(res.data);
}
}
const getlogintoken = () => {
AsyncStorage.getItem("login_token").then(res => {
if (res != null) {
setLoading(false)
setlogin_token(res)
}
else alert("No login token found")
})
}
const getConvo_details = async () => {
setLoading(true)
const res: any = await Convo_details(conversation_id, login_token)
.catch(error => {
setLoading(false)
alert(`Convo_details-->${error.message}`)
console.log("Convo_details -->");
console.log(error);
return
})
setLoading(false)
if (res.status === 200) setconversation_details(res.data)
else {
alert(`get convo details-> ${res.data.message}`)
console.log("getConvo_details -->");
console.log(res.data);
}
}
const setwelcomemsg = () => {
try {
let user = JSON.parse(currentuser)
let messages = [
{
_id: uuid.v4().toString(),
conversation_id: conversation_details.conversation_id,
created_at: new Date(),
from: conversation_details.recipient.user_uid,
type: "TEXT",
text: `About Me - ${ExpertProfile.bio}`,
user: {
_id: conversation_details.recipient.user_uid,
}
},
{
_id: uuid.v4().toString(),
conversation_id: conversation_details.conversation_id,
created_at: new Date(),
from: conversation_details.recipient.user_uid,
type: "TEXT",
text: `My name is ${conversation_details.recipient.name}`,
user: {
_id: conversation_details.recipient.user_uid,
}
},
{
_id: uuid.v4().toString(),
conversation_id: conversation_details.conversation_id,
created_at: new Date(),
from: conversation_details.recipient.user_uid,
type: "TEXT",
text: `Hi ${user.full_name}`,
user: {
_id: conversation_details.recipient.user_uid,
}
}]
setMessages(previousMessages => GiftedChat.append(previousMessages, messages))
} catch (error) {
console.log("try -> set welcome msg");
console.log(error);
return
}
}
return (
<View style={styles.maincontainer}>
<Spinner
visible={loading}
textContent={'Loading...'}
textStyle={{ color: '#FFF' }}
/>
<GiftedChat
messages={messages}
onSend={messages => onSend(messages)}
user={{
_id: currentuser.user_uid,
}}
isTyping={false}
scrollToBottom={true}
showAvatarForEveryMessage={true}
renderAvatar={() => null}
/>
</View>
);
}
export default Chat;
const styles = StyleSheet.create({
maincontainer: {
flex: 1,
},
});
When axios returns, it usually give the response as res.data, so in your case, try either res.data or res.data.yourToken (I'm not sure how it's your object).
Gurav,
As far as your code above, The api call's will trigger even before you get currentuser or loginToken. You have to handle the api call after getting the currentuser and loginToken. This can be gracefully handled with async, await.
example code:
useEffect(() => {
getData()
}, [])
useEffect(() => {
if(login_token && currentuser) {
//The api call goes here after you get the logintoken andcurrentuser.
// The above condition is just an example but will vary based on your requirements
}
}, [login_token, currentuser])
const getData = async () => {
await getlogintoken()
await getcurrentuser()
}
const getlogintoken = async () => {
await AsyncStorage.getItem("login_token").then(res => {
if (res != null) {
setLoading(false)
setlogin_token(res)
}
else alert("No login token found")
})
}
const getcurrentuser = async () => {
await AsyncStorage.getItem("currentuser").then(res => {
if (res != null) setcurrentuser(res)
else alert("Current user not found")
})
}
I am trying to store my app data on Google Drive and iCloud based on user device.I don't want to use Async Storage ,redux state neither I want to store data on my server cloud i.e. AWS. Basically I like the way how WhatsApp takes data backup on google drive for android devices and iCloud for IOS devices.This way I want to store my encrypted data's private keys on drive or iCloud so that if user changes his device I can get these keys from drive or iCloud and proceed for decryption mechanism.I found https://github.com/manicakes/react-native-icloudstore which serves my purpose for iCloud.But I haven't found anything on same line for google drive.Can you please suggest me better approach for above requirement?
For Google Drive Implementation You can Check this Package : react-native-google-drive-api-wrapper . You Have To Use Google SignIn With this package In order Get the Access Token , Install This Package Also react-native-google-signin/google-signin .
A Quick Example :
import { GoogleSignin } from "#react-native-google-signin/google-signin";
import {
GDrive,
ListQueryBuilder,
MimeTypes
} from "#robinbobin/react-native-google-drive-api-wrapper";
import React, {
useCallback,
useEffect,
useState
} from "react";
import {
AppRegistry,
Button,
SafeAreaView,
StyleSheet
} from "react-native";
import { name } from './app.json';
function App() {
const [gdrive] = useState(() => new GDrive());
const [ui, setUi] = useState();
const invoker = useCallback(async cb => {
try {
return await cb();
} catch (error) {
console.log(error);
}
}, []);
const createBinaryFile = useCallback(async () => {
console.log(await invoker(async () => (
await gdrive.files.newMultipartUploader()
.setData([1, 2, 3, 4, 5], MimeTypes.BINARY)
.setRequestBody({
name: "bin",
//parents: ["folder_id"]
})
.execute()
)));
}, [invoker]);
const createIfNotExists = useCallback(async () => {
console.log(await invoker(async () => (
await gdrive.files.createIfNotExists(
{
q: new ListQueryBuilder()
.e("name", "condition_folder")
.and()
.e("mimeType", MimeTypes.FOLDER)
.and()
.in("root", "parents")
},
gdrive.files.newMetadataOnlyUploader()
.setRequestBody({
name: "condition_folder",
mimeType: MimeTypes.FOLDER,
parents: ["root"]
})
)
)));
}, [invoker]);
const createFolder = useCallback(async () => {
console.log(await invoker(async () => (
await gdrive.files.newMetadataOnlyUploader()
.setRequestBody({
name: "Folder",
mimeType: MimeTypes.FOLDER,
parents: ["root"]
})
.execute()
)));
}, [invoker]);
const createTextFile = useCallback(async () => {
console.log(await invoker(async () => {
return (await gdrive.files.newMultipartUploader()
.setData("cm9iaW4=", MimeTypes.TEXT)
.setIsBase64(true)
.setRequestBody({
name: "base64 text",
})
.execute()).id;
}));
}, [invoker]);
const emptyTrash = useCallback(async () => {
if (await invoker(async () => {
await gdrive.files.emptyTrash();
return true;
}))
{
console.log("Trash emptied");
};
}, [invoker]);
const getWebViewLink = useCallback(async () => {
console.log(await invoker(async () => (
await gdrive.files.getMetadata(
"some_id", {
fields: "webViewLink"
}
)
)));
}, [invoker]);
const readFiles = useCallback(async () => {
console.log(await invoker(async () => (
await gdrive.files.getText("text_file_id")
)));
console.log(await invoker(async () => (
await gdrive.files.getBinary("bin_file_id", null, "1-1")
)))
}, [invoker]);
useEffect(() => {
GoogleSignin.configure({
scopes: [
"https://www.googleapis.com/auth/drive",
"https://www.googleapis.com/auth/drive.appfolder"
]});
(async () => {
if (await invoker(async () => {
await GoogleSignin.signIn();
gdrive.accessToken = (await GoogleSignin.getTokens()).accessToken;
gdrive.files.fetchCoercesTypes = true;
gdrive.files.fetchRejectsOnHttpErrors = true;
gdrive.files.fetchTimeout = 1500;
return true;
}))
{
setUi([
["create bin file", createBinaryFile],
["create folder", createFolder],
["create if not exists", createIfNotExists],
["create text file", createTextFile],
["empty trash", emptyTrash],
["get webViewLink", getWebViewLink],
["read files", readFiles]
].map(([title, onPress], index) => (
<Button
key={index}
onPress={onPress}
title={title}
/>
)));
}
})();
}, [
createBinaryFile,
createFolder,
createIfNotExists,
createTextFile,
emptyTrash,
getWebViewLink,
readFiles,
invoker
]);
return (
<SafeAreaView
style={styles.container}
>
{ui}
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
backgroundColor: "cyan",
flex: 1,
justifyContent: "space-around",
padding: 25
}
});
I followed a realm db tutorial in react native and I succeed to create, insert, delete data from DB but I have problem reading from database.
I always get same result which is not resolved and useless.
I checked my codes a lot But I cant find out my mistake.
Here is my code:
database.js
import Realm from 'realm';
export const HEART_QUEUE_SCHEMA = 'HeartQueue';
export const HeartQueueSchema = {
name : HEART_QUEUE_SCHEMA,
primaryKey : 'id',
properties: {
id : 'int', // primary key
requestTime : {type : 'string', indexed: true}
}
};
const databaseOptions = {
path: 'mizWord.realm',
schema : [HeartQueueSchema],
schemaVersion : 0,
}
export const insertToHeartQueue = (item) => new Promise((resolve, reject) => {
Realm.open(databaseOptions).then(realm => {
realm.write(()=>{
realm.create(HEART_QUEUE_SCHEMA, item);
resolve(item);
})
}).catch((error) => reject(error));
});
export const updateHeartQueue = (item) => new Promise((resolve, reject) => {
Realm.open(databaseOptions).then(realm => {
realm.write(()=>{
let updatingRow = realm.objectForPrimaryKey(HEART_QUEUE_SCHEMA, item.id);
updatingRow.requestTime = 'hello world';
resolve();
})
}).catch((error) => reject(error));
});
export const deleteHeartQueue = (itemID) => new Promise((resolve, reject) => {
Realm.open(databaseOptions).then(realm => {
realm.write(()=>{
let updatingRow = realm.objectForPrimaryKey(HEART_QUEUE_SCHEMA, itemID);
realm.delete(updatingRow);
resolve();
})
}).catch((error) => reject(error));
});
export const deleteAllHeartQueue = () => new Promise((resolve, reject) => {
Realm.open(databaseOptions).then(realm => {
realm.write(()=>{
let updatingRows = realm.objects(HEART_QUEUE_SCHEMA);
realm.delete(updatingRows);
resolve();
})
}).catch((error) => reject(error));
});
export const getAllHeartQueue = () => new Promise((resolve, reject) => {
Realm.open(databaseOptions).then(realm => {
let allHeartsList = realm.objects(HEART_QUEUE_SCHEMA);
resolve(allHeartsList);
}).catch((error) => reject(error));
});
export default new Realm(databaseOptions)
and here is my app.js file
import realm from './databases';
import {insertToHeartQueue, deleteHeartQueue, deleteAllHeartQueue, getAllHeartQueue} from './databases'
export default class App extends Component {
constructor(){
super();
this.state = {
data : "test",
time : 0,
testDB : '',
xxxz : []
}
}
_readDB = () => {
getAllHeartQueue().then((allHeartsList)=>{
console.log('data',allHeartsList);
this.setState({
xxxz : allHeartsList
})
}).catch((err)=>{
alert(err)
});
}
render() {
console.log('state', this.state.xxxz)
return (
<View style={styles.container}>
<Text style={styles.welcome}>Welcome to React Native!</Text>
<Text style={styles.welcome}>{this.state.time}</Text>
<View>
<Button
onPress={()=> this._readDB()}
title="Ask for Data"
color="#cc77v"
accessibilityLabel="Learn more about this purple button"
/>
<View>
</View>
</View>
</View>
);
}
}
bu I always get this:
Proxy {type: "object", optional: false, Symbol(realm): 140510983537104, Symbol(id): 175, …}
Try to love resolve() outside the write transactions.
I have implemented redux with my login form which is not working properly
it shows ERROR 'Cannot read property 'isAuthenticated' of undefined. which i think it means that redux is not implemented properly.
Please Help!
if you need any other file,tell me i will share it to you.
LoginForm.js
import React, {Component} from 'react';
import {
//StyleSheet,
View,
Text,
TextInput,
Button
} from 'react-native';
import {reduxForm,Field} from 'redux-form';
import {connect} from 'react-redux';
import {login} from './authActions';
const validate = values =>{
const errors = {};
if(!values.email){
errors.email="Please fill the email"
return errors;
}
if(!values.password){
errors.password="Please fill the password"
return errors;
}
}
const myFields = ({label,meta:{error,touched}, input:{onChange}}) =>{
return(
<View>
<Text>{label}</Text>
<TextInput style={{borderWidth:1,width:300,marginBottom:10}}
onChangeText={onChange}/>
{touched && (error && (<Text style={{color:'red'}}>{error}</Text>))}
</View>
);
}
const passFields = ({label,meta:{error,touched}, input:{onChange}}) =>{
return(
<View>
<Text>{label}</Text>
<TextInput style={{borderWidth:1,width:300,marginBottom:10}}
secureTextEntry={true}
onChangeText={onChange}/>
{touched && (error && (<Text style={{color:'red'}}>{error}</Text>))}
</View>
);
}
const submitbtn = values =>{
//alert(`here are the values ${JSON.stringify(values)}`);
//console.log(input.value);
this.props.login(values);
}
const myLoginForm = props => {
const {handleSubmit} = props;
return(
<View>
<Field
name="email"
component={myFields}
label="Email"/>
<Field
name="password"
component={passFields}
label="Password"
/>
<Button title="Submit"
onPress={handleSubmit(submitbtn)}/>
</View>
);
}
const LoginForm = reduxForm({
form:'loginform',
validate
})(myLoginForm);
const mapStateToProps =(state) =>({
isAuthenticated: state.auth.isAuthenticated
});
export default connect(mapStateToProps,{login})(LoginForm);
authActions.js
import axios from 'axios';
//import { returnErrors } from './errorActions';
export const register = ({username, name, email, password}) => {
return (dispatch, getState) => {
const config = {
headers : {
'Content-type' : 'Application/json'
}
}
const body = JSON.stringify({
username,
name,
email,
password
})
axios.post('http://localhost:5000/users/register', body , config )
.then(res => dispatch({
type : 'REGISTER_SUCCESS',
payload : res.data
}))
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status, 'REGISTER_FAIL'));
dispatch({
type : 'REGISTER_FAIL'
})
});
};
};
export const login = ({username, password}) => {
return (dispatch, getState) => {
const config = {
headers : {
'Content-type' : 'Application/json'
}
}
const body = JSON.stringify({
username,
password
})
axios.post('http://localhost:5000/users/login', body , config )
.then(res => dispatch({
type : 'LOGIN_SUCCESS',
payload : res.data
}))
.catch(err => {
dispatch(returnErrors(err.response.data, err.response.status, 'LOGIN_FAIL'));
dispatch({
type : 'LOGIN_FAIL'
})
});
};
}
export const logout = () => {
return {
type : 'LOGOUT_SUCCESS'
}
}
export const loadUser = () => {
return (dispatch, getState) => {
dispatch({
type: 'USER_LOADING',
});
axios.get('http://localhost:5000/users/auth' , tokenConfig(getState))
.then(res => dispatch({
type: 'USER_LOADED',
payload : res.data
}))
.catch(err => {
dispatch(returnErrors(err.response.data.message, err.response.status));
dispatch({
type : 'AUTH_ERROR'
});
})
}
}
//
export const tokenConfig = (getState) => {
const token = getState().auth.token;
const config = {
headers : {
'content-type' : 'Application/json',
}
}
if(token) {
config.headers['auth'] = token;
}
return config;
}
authReducer.js
const initState = {
toke: localStorage.getItem('token'),
isAuthenticated: null,
isLoading: null,
user: null
};
const authReducer = (state = initState, action) => {
switch(action.type){
case 'USER_LOADING':
return{
...state,
isLoading: true
}
case 'USER_LOADED':
return{
...state,
isLoading: false,
isAuthenticated:true,
user:action.payload
}
case 'REGISTER_SUCCESS':
case 'LOGIN_SUCCESS':
localStorage.setItem('token', action.payload.token)
return{
...state,
...action.payload,
isLoading: false,
isAuthenticated:true,
}
case 'AUTH_ERROR':
case 'LOGOUT_SUCCESS':
case 'LOGIN_FAIL':
case 'REGISTER_FAIL':
localStorage.removeItem('token')
return{
token: null,
user: null,
isLoading: false,
isAuthenticated:false,
}
default:
return state;
}
}
export default authReducer
Please check file where you combine your reducers, there's possibility that you put your reducer as something other than "auth" or even you forgotten to put the reducer here.
You can install "redux-devtools-extension" package and it's chrome extension to see which reducers are connected to your redux state and debug it more easily. Also, redux-form requires you to pass the form reducer you create along with all the other reducers you have in 'combineReducers'. Follow the instructions on their docs https://redux-form.com/8.2.2/docs/gettingstarted.md/
hope this helps :)
I am having troubles with getting the state in my HomeComponent.js . Every time I try to print it, it return "undefined" .
I've tried different ways to call onPress in my Home component (e.g. onPress={this.printState()}, but none work)
This is my HomeComponent.js
//import statements
const mapStateToProps = state => {
return {
jobTitles: state.jobTitles
}
}
const mapDispatchToProps = dispatch => ({
fetchJobTitles: () => dispatch(fetchJobTitles())
});
class Home extends Component {
constructor(props) {
super(props);
this.state = {
jobInputValue: '',
addressInputValue: ''
};
}
componentDidMount() {
this.props.fetchJobTitles();
}
printState = () => {
console.log('State is: ' +
JSON.stringify(this.state.jobTitles));
}
render() {
return (
<ImageBackground style={styles.bkgImage} source={require('../assets/homepage_background.jpg')}>
//JSX goes here
<Button
title="CAUTĂ"
type="outline"
underlayColor={colors.red}
titleStyle={styles.buttonTitleStyle}
color={colors.red}
style={styles.buttonStyle}
onPress={this.printState}
/>
</ImageBackground>
);
}
}
//some styles
export default connect(mapStateToProps, mapDispatchToProps)(Home);
This is my reducer (jobTitles.js):
import * as ActionTypes from '../ActionTypes';
export const jobTitles = (state = { errMess: null,
jobTitles:[]}, action) => {
switch (action.type) {
case ActionTypes.GET_JOB_TITLES:
return {...state, errMess: null, jobTitles: action.payload};
case ActionTypes.JOB_TITLES_FAILED:
return {...state, errMess: action.payload};
default:
return state;
}
};
And this is my Action Creator:
import * as ActionTypes from './ActionTypes';
import { baseUrl } from '../shared/baseUrl';
export const fetchJobTitles = () => (dispatch) => {
return fetch(baseUrl + 'api/jobs/job_keywords')
.then(response => {
if (response.ok) {
return response;
} else {
var error = new Error('Error ' + response.status + ': ' +
response.statusText);
error.response = response;
throw error;
}
},
error => {
var errmess = new Error(error.message);
throw errmess;
})
.then(response => response.json())
.then(jobTitles => dispatch(addJobTitles(jobTitles)))
.catch(error => dispatch(jobTitlesFailed(error.message)));
};
export const jobTitlesFailed = (errmess) => ({
type: ActionTypes.JOB_TITLES_FAILED,
payload: errmess
});
export const addJobTitles = (jobTitles) => ({
type: ActionTypes.GET_JOB_TITLES,
payload: jobTitles
});
This is how the response from the API looks like:
"jobTitles": Object {
"results": Array [
"Engineer",
"Software",
"Software Architect",
"Software Consultant",
"Solution Architect",
"System Architect"
]
}
I expected the console.log() statement from the print() function in the HomeComponent.js to print the JSON response from the API, but instead it returns "undefined". Any ideas why?
Any help will be greatly appreaciated!
In your code :
this.state = {
jobInputValue: '',
addressInputValue: ''
};
What you try to print :
this.state.jobTitles
Of course it's undefined ! Either log this.props.jobTitles or set state jobTitles to print what you want.
You should use this.props.jobTitles
The mapStateToProps puts data from the redux state into the props of the component. this.state only holds the local state of the component. So jobInputValue and addressInputValue in this case. Everything from mapStateToProps and mapDispatchToProps will end up in the props. (As the name of the function indicates)