JSONparse won't do with Asyncstorage retrieved item - react-native

I'm coding a simple app, and I want to store the user info on the device, and include them in a POST request without keep asking the user for them. So I thought: "let's save them on the device!".
I've managed to store them, but when I retrieve them, I just can't figure how to JSONparse it back to a dict.
Here's what I get when I call the AsyncStorage.getItem:
I/ReactNativeJS(31854): ## STORAGE - Data retrieved: [object Object]
And when I try to pass that through JSONparse, I get "JSON Parse error: Unexpected identifier 'undefined'"
Here's my code:
storage.js:
import React, { Component } from 'react';
import {
AsyncStorage,
} from 'react-native';
module.exports = {
save: function(key, data){
//console.log(save key:${key} data:${data} stringify:${JSON.stringify(data)});
try {
AsyncStorage.setItem(key, JSON.stringify(data));
//console.log(Storage.save() key => value, ${key} => ${JSON.stringify(data)});
return true;
} catch(err) {
//console.log(save: ERROR ${err});
return false;
}
},
read: async function(key) {
//console.log(reading key:${key});
try {
var data = await AsyncStorage.getItem(key);
if (data !== null){
//console.log("Storage.read(): " + typeof(JSON.parse(data)) + ":" + JSON.parse(data));
return JSON.parse(data);
}else {
//console.log("Storage.read(): Not found");
return false;
}
} catch (err) {
//console.log('Storage.read(): error: ' + err.message);
return false;
}
},
empty: function(key){
try {
AsyncStorage.setItem(key, '');
//console.log(Storage.empty: cleaning key ${key});
return true;
} catch(err) {
//console.log(Storage.empty: ERROR ${err});
return false;
}
}
}
index.android.js:
import React, { Component } from 'react';
import {
AppRegistry,
StyleSheet,
View,
TouchableHighlight,
Alert,
Image,
AsyncStorage,
TextInput,
} from 'react-native';
import { Container, Button, Text } from 'native-base';
import BackgroundImage from './background.js'
var storage = require('./storage.js');
var form_style = require('./formstylesheet.js');
var t = require('tcomb-form-native');
var Form = t.form.Form;
var Person = t.struct({
Nombre: t.String,
Apellido: t.String,
Celular: t.String,
Lote: t.String,
});
var options = {
stylesheet: form_style
};
class UserInfo extends Component {
onPress() {
var value = this.refs.form.getValue();
storage.save('username', JSON.stringify(value.Nombre));
var data = storage.read('username');
}
render() {
return (
<Image source={require('./images/background.jpg')} style={styles.image_container}>
<View style={styles.input_container}>
<Form
ref="form"
type={Person}
options={options}
/>
<TouchableHighlight style={styles.save_button} onPress={this.onPress.bind(this)} underlayColor='#99d9f4'>
<Text style={styles.buttonText}>Guardar</Text>
</TouchableHighlight>
</View>
</Image>
)
}
}
Not sure if everything needed to solve the problem is in here. Please let me know if I'm missing something, or there's more snippets needed.
Thanks in advance!

Related

Use value from AsyncStorage for VideoThumbnails.getThumbnailAsync

I'm trying to use the expo-video-thumbnails package to generate a thumbnail from a video uri. The video uri is retrieved from async-storage. I get the following error
Argument of an incompatible class: class java.util.HashMap cannot be
passed as an argument to parameter expecting class java.lang.String.
If I use a static video uri, it works fine. I can't seem to get this to work with the value from AsyncStorage. Here's my code:
import React, { useState, useEffect } from 'react';
import { View, Image } from 'react-native';
import AsyncStorage from '#react-native-async-storage/async-storage';
import * as VideoThumbnails from 'expo-video-thumbnails';
export default function ThumbnailsScreen() {
// video uri
const [videoUri, setVideoUri] = React.useState({});
const getData = async () => {
try {
const value = await AsyncStorage.getItem('#lastRecordedVideo')
if(value !== null) {
setVideoUri(value)
}
} catch(e) {
console.log(e);
}
}
getData();
// thumbnails
const [image, setImage] = useState(null);
const generateThumbnail = async () => {
try {
const { uri } = await VideoThumbnails.getThumbnailAsync(
videoUri,
{
time: 1000,
}
);
setImage(uri);
} catch (e) {
console.warn(e);
}
};
useEffect(() => { generateThumbnail(); }, [])
return (
<View>
{image && <Image source={{ uri: image }} /> }
</View>
)
}

TypeError : undefined not an object - AsyncStorage

Hi I cant seem to solve this issue - I am using AsyncStorage in a React Native component to load file path strings. I am getting the below error when the component mounts and failing to see what I am doing incorrectly here as it pretty much follows the documented examples.
any help would be appreciated.
"TypeError: undefined is not an object (evaluating '_asyncStorage.AsyncStorage.getKeys')
here is my code :
import React, { Component } from 'react';
import BasicCard from './cards'
import {AsyncStorage} from '#react-native-community/async-storage'
import {
StyleSheet,
ScrollView,
} from 'react-native';
class NewPost extends Component{
state={
content:[]
}
componentDidMount(){
this.getContent(this.getKeys())
}
getKeys = async () => {
try{
return await AsyncStorage.getKeys()
}catch (e) {
alert(e)
}
}
getContent = async (keys) => {
try{
await AsyncStorage.multiGet(keys, store)
this.setState({content:store})
} catch (e) {
alert ( e )
}
}
render(){
return(
<ScrollView style={styles.container}>
{this.state.content.map((result,i,item) => (
<BasicCard
imgName={item[i][0]}
imgPath={item[i[1]]} />
))}
</ScrollView>
)
}
}
export default NewPost;
const styles = StyleSheet.create({
container: {
flex: 1,
flexDirection: 'column',
backgroundColor: 'black',
},
});
There is no function called getkeys in asyncStorage
refer this link to know the available functions in async storage
getKeys = async () => {
try{
return await AsyncStorage.getKeys()
}catch (e) {
alert(e)
}
}
change to this
getKeys = async () => {
try{
return await AsyncStorage.getAllKeys()
}catch (e) {
alert(e)
}
}

TypeError: undefined is not a function (near '..._fire.default.get...')

When I try to enter username and then go on next screen for live chating then I facing this error.
Here is code for ChatScreen.js file.
TypeError: undefined is not a function (near '..._fire.default.get...').
ChatScreen.js
import React,{Component} from "react";
import {Platform,KeyboardAvoidingView} from 'react-native';
import {GiftedChat}from 'react-native-gifted-chat-fix';
import{SafeAreaView}from 'react-native-safe-area-view';
import Video from 'react-native-video';
import Fire from '../fire';
export default class ChatScreen extends Component{
state={
messages:[]
}
get user(){
return{
_id:Fire.uid,
name:this.props.navigation.state.params.name
}
}
componentDidMount(){
Fire.get(message=>this.setState(previous=>({
messages:GiftedChat.append(previous.messages,message)
}))
);
}
componentWillUnmount(){
Fire.off()
}
render(){
const chat=<GiftedChat messages={this.state.messages} onSend={Fire.send} user={this.user}/>;
if(Platform.OS=='android'){
return(
<KeyboardAvoidingView style={{flex:1}}behavior="padding" keyboardVerticalOffset={30} enabled>
{chat}
</KeyboardAvoidingView>
);
}
return<SafeAreaView style={{flex:1}}>{chat}</SafeAreaView>;
}
}
Try changing the code in both files
At first in Fire.js
import firebase from 'firebase'; // 4.8.1
class Fire {
constructor() {
this.init();
this.observeAuth();
}
init = () => {
if (!firebase.apps.length) {
firebase.initializeApp({
apiKey:'AIzaSyAPfes9_2EwZESX1puYMUv29yunzK9Ve5U',
authDomain:'docman-31d96.firebaseapp.com',
databaseURL: "https://docman-31d96.firebaseio.com",
projectId: "docman-31d96",
storageBucket: "docman-31d96.appspot.com",
messagingSenderId: "649332068608",
appId:'1:649332068608:android:08c080ee6a4e521f5323e5'
});
}
};
observeAuth = () =>
firebase.auth().onAuthStateChanged(this.onAuthStateChanged);
onAuthStateChanged = user => {
if (!user) {
try {
firebase.auth().signInAnonymously();
} catch ({ message }) {
alert(message);
}
}
};
get uid() {
return (firebase.auth().currentUser || {}).uid;
}
get ref() {
return firebase.database().ref('messages');
}
parse = snapshot => {
const { timestamp: numberStamp, text, user } = snapshot.val();
const { key: _id } = snapshot;
const timestamp = new Date(numberStamp);
const message = {
_id,
timestamp,
text,
user,
};
return message;
};
on = callback =>
this.ref
.limitToLast(20)
.on('child_added', snapshot => callback(this.parse(snapshot)));
get timestamp() {
return firebase.database.ServerValue.TIMESTAMP;
}
// send the message to the Backend
send = messages => {
for (let i = 0; i < messages.length; i++) {
const { text, user } = messages[i];
const message = {
text,
user,
timestamp: this.timestamp,
};
this.append(message);
}
};
append = message => this.ref.push(message);
// close the connection to the Backend
off() {
this.ref.off();
}
}
Fire.shared = new Fire();
export default Fire;
and then in ChatScreen.js
import * as React from 'react';
import { Platform , KeyboardAvoidingView,SafeAreaView } from 'react-native';
// #flow
import { GiftedChat } from 'react-native-gifted-chat'; // 0.3.0
import Fire from '../fire';
type Props = {
name?: string,
};
class ChatScreen extends React.Component<Props> {
static navigationOptions = ({ navigation }) => ({
title: (navigation.state.params || {}).name || 'Chat!',
});
state = {
messages: [],
};
get user() {
return {
name: this.props.navigation.state.params.name,
_id: Fire.shared.uid,
};
}
render() {
const chat=<GiftedChat messages={this.state.messages} onSend={Fire.shared.send} user={this.user}/>;
if(Platform.OS=='android'){
return(
<KeyboardAvoidingView style={{flex:1}}behavior="padding" keyboardVerticalOffset={0} enabled>
{chat}
</KeyboardAvoidingView>
);
}
return<SafeAreaView style={{flex:1}}>{chat}</SafeAreaView>;
}
componentDidMount() {
Fire.shared.on(message =>
this.setState(previousState => ({
messages: GiftedChat.append(previousState.messages, message),
}))
);
}
componentWillUnmount() {
Fire.shared.off();
}
}
export default ChatScreen;
This helped for me It should work for you too
To see my chat app just visit https://snack.expo.io/#habibishaikh1/chatapp

It gives this error while running: undefined is not a function (evaluating '_reactNativr.default.createElement')

This section of code is not running it always return en error saying undefined or not a function in the render function().
Heading
'use strict';
import React, {
AppRegistry,
StyleSheet,
Text,
View,
TouchableHighlight,
AlertIOS,
Dimensions,
BackHandler,
PropTypes,
Component,
} from 'react-native';
import NavigationExperimental from 'react-native-deprecated-custom-
components';
var _navigator;
//var Navipanel=require('./App/Navigation/Navipanel.js');
var Dashboard= require('./App/Dashboard/dashboard.js');
//var Sample= require('./App/Navigation/sample.js');
var Matches = require('./App/Components/Matches.js');
var Users = require('./App/Components/Users.js');
var SCREEN_WIDTH =require('Dimensions').get('window').width;
var BaseConfig=NavigationExperimental.Navigator.SceneConfigs.FloatFromRight;
var CustomLeftToRightGesture = Object.assign({}, BaseConfig.gestures.pop,
{
snapVelocity: 8,
edgeHitWidth: SCREEN_WIDTH,
});
BackHandler.addEventListener('hardwareBackPress', () => {
if (_navigator.getCurrentRoutes().length === 1) {
return false;
}
_navigator.pop();
return true;
});
var CustomSceneConfig = Object.assign({}, BaseConfig, {
// A very tighly wound spring will make this transition fast
springTension: 100,
springFriction: 1,
// Use our custom gesture defined above
gestures: {
pop: CustomLeftToRightGesture,
}
});
//var createReactElement = require('create-react-element');
var createReactClass = require('create-react-class');
var test = createReactClass({
_renderScene(route,navigator) {
_navigator = navigator;
if (route.id === 1) {
return <Dashboard navigator={navigator}/>;
}
else if(route.id === 2) {
return <Sample navigator={navigator} /> ;
}
else if(route.id === 3) {
return <Navipanel navigator={navigator} /> ;
}
else if(route.id === 4){
return <Matches navigator={navigator} /> ;
}
else if(route.id === 5) {
return <Users navigator={navigator} />
}
},
_configureScene(route) {
return CustomSceneConfig;
},
render:function() {
return (
<NavigationExperimental.Navigator [//error in this line]
initialRoute = {{id:1}}
renderScene = {this._renderScene}
configureScene = {this._configureScene} />
);
}
});
Undefined error _reactNative.default.createElement
You imported React from "react-native";
import React, {
AppRegistry,
StyleSheet,
Text,
View,
TouchableHighlight,
AlertIOS,
Dimensions,
BackHandler,
PropTypes,
Component,
} from 'react-native';
instead of this, you need to import React from "react";
import React from 'react';
When we use JSX in our render functions, in the background JSX runs React.createElement(...). And in your code, React is not defined. Because of this, it gives that error.

ReactNative and NativeBase Radio

I've tried to change the radio value in ReactNative App with NativeBase template. I want to get or set value from the radio after click it, exactly checked or not. But couldn't find a way to get or set value to it. Even the radio button never changed on the screen after click. The codes are like as below:
import React, { Component } from 'react';
import { TouchableOpacity, Image, View } from 'react-native';
import { connect } from 'react-redux';
import { actions } from 'react-native-navigation-redux-helpers';
import {
Container,
Header,
Title,
Content,
Text,
Button,
Icon,
InputGroup,
Input,
List,
ListItem,
Radio, } from 'native-base';
import { openDrawer } from '../../actions/drawer';
import { Col, Row, Grid } from 'react-native-easy-grid';
import styles from './styles';
import dimension from './global';
import Swiper from 'react-native-swiper';
const imgBoy = require('../../../images/icon_boy.png');
const imgGirl = require('../../../images/icon_girl.png');
const {
popRoute,
} = actions;
class SessionPage extends Component {
static propTypes = {
name: React.PropTypes.string,
index: React.PropTypes.number,
list: React.PropTypes.arrayOf(React.PropTypes.string),
openDrawer: React.PropTypes.func,
popRoute: React.PropTypes.func,
navigation: React.PropTypes.shape({
key: React.PropTypes.string,
}),
}
popRoute() {
this.props.popRoute(this.props.navigation.key);
}
constructor(props) {
super(props);
// console.log(this.props.navigation);
this.state = {
sliderCount : parseInt(this.props.navigation.behavior.length / 5) + 1,
sliderArray : [],
selected : false,
}
this.getSliderArray();
console.log(this.state);
}
getSliderArray() {
for (var i = 0; i < this.state.sliderCount; i++) {
var childArray = [];
for (var j = i * 5; j < 5 * (i + 1); j++) {
if (this.props.navigation.behavior[j] != null){
var unit = this.props.navigation.behavior[j];
unit.selected = true;
childArray.push(unit);
}
}
this.state.sliderArray.push({
index : i,
behaviors : childArray
})
}
}
selectRadio(i, j){
this.state.sliderArray[i].behaviors[j].selected = true;
}
render() {
const { props: { name, index, list } } = this;
return (
<Container style={styles.container}>
<Swiper style={styles.wrapper}
height={dimension.Height - 400}
width={dimension.Width - 40}
showsButtons={false}
showsPagination={true}>
{this.state.sliderArray.map((item, i) =>
<View style={styles.slide1} key={i}>
{item.behaviors.map((subitem, j) =>
<ListItem key={i + "-" + j} style={styles.cardradio}>
<Radio selected={this.state.sliderArray[i].behaviors[j].selected} onPress={() => this.selectRadio(i, j)} />
<Text>{subitem.behaviorName}</Text>
</ListItem>
)}
</View>
)}
</Swiper>
</Content>
</Container>
);
}
}
function bindAction(dispatch) {
return {
openDrawer: () => dispatch(openDrawer()),
popRoute: key => dispatch(popRoute(key)),
};
}
const mapStateToProps = state => ({
navigation: state.cardNavigation,
name: state.user.name,
index: state.list.selectedIndex,
list: state.list.list,
});
export default connect(mapStateToProps, bindAction)(SessionPage);
selectRadio(i, j){
this.state.sliderArray[i].behaviors[j].selected = true; <== This is the problem
}
When you call this.state = something after the component has mounted, it doesn't trigger update method of component life cycle. Hence view will not be updated.
You should be using this.setState() to update your views
this.setState({
slider = something
})
For more info, refer docs
this.setState() is an async method. After you make changes in getSliderArray(), it may not be reflected in immediate console.log
this.getSliderArray();
console.log(this.state);
You can pass callback to this.setState() to perform any action only after state is changed
this.setState({
// new values
}, function() {
// Will be called only after switching to new state
})